package com.xoa.service.work.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.xoa.dao.WFE.WFEFlowProcessMapper;
import com.xoa.dao.WFE.WFEFlowRunPrcsMapper;
import com.xoa.dao.attend.AttendLeaveMapper;
import com.xoa.dao.common.SysParaMapper;
import com.xoa.dao.flowhook.FlowHookMapper;
import com.xoa.dao.flowplugin.FlowPluginMapper;
import com.xoa.dao.notify.NotifyMapper;
import com.xoa.dao.users.UsersMapper;
import com.xoa.dao.work.WorkMapper;
import com.xoa.dao.workflow.*;
import com.xoa.dev.qywx.service.QywxService;
import com.xoa.global.proxy.TriggerUtils.Trigger;
import com.xoa.model.common.SysPara;
import com.xoa.model.department.Department;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.flowRunFeedback.FlowRunFeedback;
import com.xoa.model.flowplugin.FlowPluginModel;
import com.xoa.model.notify.Notify;
import com.xoa.model.sms.SmsBody;
import com.xoa.model.users.Users;
import com.xoa.model.workflow.*;
import com.xoa.service.WFE.WFERunner.WFEFlowRunPrcs;
import com.xoa.service.department.DepartmentService;
import com.xoa.service.email.impl.EmailServiceImpl;
import com.xoa.service.enclosure.EnclosureService;
import com.xoa.service.sms.SmsService;
import com.xoa.service.smsDelivery.Sms2PrivService;
import com.xoa.service.smsDelivery.impl.Sms2PrivServiceImpl;
import com.xoa.service.users.UsersService;
import com.xoa.service.work.WorkFlowServiceContext;
import com.xoa.service.work.WorkService;
import com.xoa.util.*;
import com.xoa.util.common.L;
import com.xoa.util.common.StringUtils;
import com.xoa.util.common.constants.DocumentConstants;
import com.xoa.util.common.session.SessionUtils;
import com.xoa.util.common.wrapper.BaseWrapper;
import com.xoa.util.dataSource.ContextHolder;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@SuppressWarnings("all")
public class WorkServiceImpl implements WorkService {

    @Resource
    private UsersService usersService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private EnclosureService enclosureService;

    @Resource
    private FlowTiggerMapper flowTiggerMapper;

    @Resource
    private FlowPluginMapper flowPluginMapper;

    @Resource
    private EmailServiceImpl emailService;
    //工作流 Context 类
    @Resource
    private WorkFlowServiceContext workFlowServiceContext;

    @Autowired
    private FlowHookMapper flowHookMapper;

    @Autowired
    private AttendLeaveMapper attendLeaveMapper;

    @Resource
    private FlowRunMapper flowRunMapper;

    @Resource
    private FlowRunPrcsMapper flowRunPrcsMapper;
    @Resource
    private SmsService smsService;
    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private WFEFlowProcessMapper wfeFlowProcessMapper;
    @Autowired
    Sms2PrivServiceImpl sms2PrivServiceImpl;

    @Autowired
    Sms2PrivService sms2PrivService;

    @Autowired
    WorkMapper workMapper;

    @Autowired
    UsersMapper usersMapper;

    @Autowired
    private FlowRunLogMapper flowRunLogMapper;

    @Autowired
    private WFEFlowRunPrcs wfeFlowRunPrcs;

    @Resource
    private WFEFlowRunPrcsMapper wfeFlowRunPrcsMapper;

    @Autowired
    private FlowRuleMapper flowRuleMapper;

    @Resource
    private QywxService qywxService;

    @Autowired
    private NotifyMapper notifyMapper;

    @Resource
    private SysParaMapper sysParaMapper;

    public void init() {
       // System.out.println("this is init method1");
    }

    /*   public WorkFlowServiceContext getWorkFlowServiceContext() {
           return workFlowServiceContext;
       }

       public void setWorkFlowServiceContext(WorkFlowServiceContext workFlowServiceContext) {
           this.workFlowServiceContext = workFlowServiceContext;
       }
   */
    @Override
    public ToJson<FlowFast> nextwork(String flowId, String formdata, String modifydata, String formlength, int runId,
                                     String runName, String beginTime, String beginUser, String sqlType, String prcsId, String fromDateReject, String tableNameother, String tabId,
                                     String flowPrcs, HttpServletRequest request) {
        ToJson<FlowFast> tj = new ToJson<FlowFast>();
        //用来存储sql传入参数
        Map<String, Object> param = new HashMap();
        JSONArray json = new JSONArray();

        String tableName = "flow_data_" + flowId;
        //表单上所有的数据
        List<Map<String, Object>> l = json.parseObject(formdata, List.class);

        List<Map<String, Object>> lAll = new ArrayList<Map<String, Object>>();
        //处理异常数据
        for (int i = 0; i < l.size(); i++) {
            if (l.get(i).size() == 2) {
                lAll.add(l.get(i));
            }
        }
        //此段代码只为添加对前端传入参数的异常处理
        List<String> keyc = new ArrayList<String>();
        for (Map<String, Object> map : l) {
            if (keyc.contains(map.get("key"))) {
                tj.setMsg("There are duplicate fields in the form parameter!");
                tj.setFlag(1);
                return tj;
            }
            keyc.add((String) map.get("key"));
        }

        //表单上有值需要更新的数据
        List<Map<String, Object>> modify = json.parseObject(modifydata, List.class);
        List<Map<String, Object>> mAll = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < modify.size(); i++) {
            if (modify.get(i).size() == 2) {
                mAll.add(modify.get(i));
            }
        }
        //StringBuffer sbcreate = new StringBuffer();
        try {
            //获取该表数据库中的所有的列
            List<String> columns = this.createTable(tableName, sqlType, lAll);
            if (columns.size() > 0) {
                //用于存储数据库插入的字段
                List<String> key = new ArrayList<String>();
                //用于存储新增字段
                List<String> unusual = new ArrayList<String>();
                //用于获取传入表单上的所有key值
                List<String> Allkey = new ArrayList<String>();
                //用于存储已删除字段
                List<String> delkey = new ArrayList<String>();
                //遍历表单数据获取新增字段和所有
                for (Map<String, Object> map : lAll) {
                    if (!columns.contains((String) map.get("key"))) {
                        //添加新增的表字段
                        unusual.add((String) map.get("key"));
                    }
                    //获取所有表单传入键值
                    Allkey.add((String) map.get("key"));
                }
                //移除数据库中前八个字段

                Iterator<String> it = columns.iterator();
                while (it.hasNext()) {
                    String x = it.next();
                    if (!x.toUpperCase().contains("DATA")) {
                        it.remove();
                    }
                }
                //存储表单可能删除的列
                for (int i = 0; i < columns.size(); i++) {
                    if (!Allkey.contains(columns.get(i))) {
                        delkey.add(columns.get(i));
                    }
                }
                //添加表的列
                if (unusual.size() > 0) {
                    param.put("tableName", tableName);
                    param.put("keys", unusual);
                    workFlowServiceContext.getWorkMapper().addcolumn(param);
                }

                Map<String, Object> maps = new HashMap<String, Object>();
                maps.put("tableName", tableName);
                maps.put("runId", runId);
                //查询该表单的信息
                Map<String, Object> m = workFlowServiceContext.getWorkMapper().select(maps);
                key = new ArrayList<String>();
                List<String> value = new ArrayList<String>();
                if (m == null || m.size() == 0) {
                    key.add("run_id");
                    value.add(String.valueOf(runId));
                    key.add("run_name");
                    value.add(runName);
                    key.add("begin_time");
                    value.add(beginTime);
                    key.add("begin_user");
                    value.add(beginUser);
                    //第一次不能根据此判断
                  /*  List<String> listmodify = new ArrayList<String>();
                    for (Map<String, Object> mapmodify : modify) {
                        key.add((String) mapmodify.get("key"));
                        value.add((String) mapmodify.get("value"));
                        listmodify.add((String) mapmodify.get("key"));
                    }*/
                    /*for (Map<String, Object> map : l) {
                        if (!listmodify.contains((String) map.get("key"))) {
                            key.add((String) map.get("key"));
                            value.add("");
                        }
                    }*/

                    for (Map<String, Object> map : lAll) {
                        key.add((String) map.get("key"));
                        value.add((String) map.get("value"));
                    }

                    //表单可能删除的列
                    for (String s : delkey) {
                        key.add(s);
                        value.add("");
                    }
                    param.put("tableName", tableName);
                    param.put("keys", key);
                    param.put("values", value);
                    workFlowServiceContext.getWorkMapper().insert(param);
                } else {
                    if (mAll.size() != 0) {
                        for (Map<String, Object> map : mAll) {
                            if (!StringUtils.checkNull((String) map.get("value"))) {
                                key.add((String) map.get("key") + "=" + "'" + (String) map.get("value") + "'");
                            }
                        }
                        param.put("tableName", tableName);
                        param.put("keys", key);
                        param.put("runId", String.valueOf(runId));
                        workFlowServiceContext.getWorkMapper().update(param);
                    }
                }
            }
            //    Map<Object,Object> maps=new HashMap<Object,Object>();
            //触发器设置
            // 域名获取，不包含端口号
//            String url =request.getScheme()+"://"+ request.getServerName()+"/";//+request.getRequestURI();

            TriggerPlugIn triggerPlugIn = new TriggerPlugIn();
            triggerPlugIn.setFlowId(flowId);
            triggerPlugIn.setFormmat("2");//超链接格式//适用公告
            triggerPlugIn.setFromId(beginUser);
            triggerPlugIn.setSendTime(DateFormat.getDate(beginTime));
            triggerPlugIn.setSubject(runName);
            String url = request.getScheme() + "://" + request.getServerName() + ":" +
                    request.getServerPort() + "/workflow/work/workformPreView?flowId=" + Integer.valueOf(flowId) + "&flowStep=" + Integer.valueOf(prcsId) + "&runId=" + runId + "";
            triggerPlugIn.setContent("<a href=" + url + ">" + url + "</a>");
            triggerPlugIn.setToId2("");
            triggerPlugIn.setFlowPrcs(flowPrcs);
            triggerPlugIn.setPrcsId(prcsId);
            triggerPlugIn.setModify(modifydata);
            triggerPlugIn.setReject(fromDateReject);
            triggerPlugIn.setTableName(tableNameother);
            triggerPlugIn.setRunId(runId + "");
            triggerPlugIn.setRunName(runName);
            Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
            Users user = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
            triggerPlugIn.setUsers(user);
            triggerPlugIn.setFlag(this.returnMap().get(turn));
            triggerPlugIn.setRequest(request);
            triggerPlugIn.setSqlType(sqlType);
            triggerPlugIn.setTabId(tabId);
            this.notifyNotice(triggerPlugIn);


            tj.setMsg("OK");
            tj.setFlag(0);
        } catch (Exception e) {
            tj.setMsg(e.getMessage());
            tj.setFlag(1);
            tj.setMsg("false");
            L.e("work nextwork:" + e);
        }
        return tj;
    }

    //建表,如果没有则新建
    public List<String> createTable(String tableName, String sqlType, List<Map<String, Object>> l) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("tableName", tableName);
        if (StringUtils.checkNull(sqlType)) {
            param.put("tableSchema", "xoa1001");
        } else {
            param.put("tableSchema", sqlType);
        }
        //获取该表所有的列
        try {
            List<String> columns = workFlowServiceContext.getWorkMapper().showColumns(param);
            //没有表则新建
            if (columns.size() == 0) {
                List<String> key = new ArrayList<String>();
                for (Map<String, Object> map : l) {
                    key.add((String) map.get("key"));
                }
                Map<String, Object> param1 = new HashMap();
                param1.put("tableName", tableName);
                param1.put("keys", key);
                workFlowServiceContext.getWorkMapper().createTable(param1);
                columns = workFlowServiceContext.getWorkMapper().showColumns(param);
            }
            return columns;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    @Override
    public Map<String, Object> fastAdd(String runId, String flowId) {
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("tableName", "flow_data_" + flowId);
        maps.put("runId", runId);
        Map<String, Object> m = new HashMap<String, Object>();
        try {
            Map<String, Object> map = workFlowServiceContext.getWorkMapper().select(maps);
            if (map.size() != 0) {
                m.put("obj", map);
                m.put("flag", true);
                m.put("msg", "OK");
            } else {
                m.put("flag", false);
                m.put("msg", false);
            }
        } catch (Exception e) {
            m.put("flag", false);
            m.put("msg", false);
        }
        return m;
    }

    @Override
    public ToJson<Attachment> workUpload(MultipartFile[] files, String company, String module, String runId) {
        ToJson<Attachment> json = new ToJson<Attachment>();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            List<Attachment> list = enclosureService.upload(files, company, module);
            FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(runId));
            String attcahmentId = flowRun.getAttachmentId();
            String attachmentName = flowRun.getAttachmentName();
            StringBuffer id = new StringBuffer();
            StringBuffer name = new StringBuffer();
            if (attcahmentId != "" || attachmentName != "") {
                id.append(attcahmentId);
                name.append(attachmentName);
            }
            //返回附件信息拼接后的id和name
            Object[] o = FileUploadUtil.reAttachmentAll(list);
            map.put("runId", runId);
            map.put("attachmentId", o[0].toString());
            map.put("attachmentName", o[1].toString());
            workFlowServiceContext.getFlowRunService().updateAttachment(map);
            json.setObj(list);
            json.setMsg("OK");
            json.setFlag(0);
        } catch (Exception e) {
            json.setMsg(e.getMessage());
            json.setFlag(1);
        }
        return json;
    }

    @Override
    public ToJson<Attachment> findworkUpload(String runId, String company) {
        ToJson<Attachment> json = new ToJson<Attachment>();
        try {
            //定义用于存储附件信息的集合
            List<Attachment> attachmentList = new ArrayList<Attachment>();
            FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(runId));
            if (flowRun.getAttachmentId() != "" || flowRun.getAttachmentName() != "") {
                String attachmentId[] = flowRun.getAttachmentId().split(",");
                String attachmenName[] = flowRun.getAttachmentName().split("\\*");

                for (int i = 0; i < attachmentId.length; i++) {
                    String aid = attachmentId[i].substring(0, attachmentId[i].indexOf('@'));
                    String ym = attachmentId[i].substring(attachmentId[i].indexOf('@') + 1, attachmentId[i].indexOf('_'));
                    String attachId = attachmentId[i].substring(attachmentId[i].indexOf('_') + 1, attachmentId[i].indexOf('*'));
                    String fileSize = attachmentId[i].substring(attachmentId[i].indexOf('*') + 1, attachmentId[i].indexOf('|'));
                    String time = attachmentId[i].substring(attachmentId[i].indexOf('|') + 1, attachmentId[i].length());
                    String attachName = attachmenName[i];
                    Attachment attachment = new Attachment();
                    String attUrl = "AID=" + aid + "&" + "MODULE=" + ModuleEnum.WORKFLOW.getName() + "&" + "COMPANY=" + company + "&" +
                            "YM=" + ym + "&" + "ATTACHMENT_ID=" + attachId + "&" + "ATTACHMENT_NAME=" + attachName;
                    attachment.setAid(Integer.parseInt(aid));
                    attachment.setYm(ym);
                    attachment.setAttachId(attachId);
                    attachment.setAttachName(attachName);
                    attachment.setAttUrl(attUrl);
                    attachment.setFileSize(fileSize);
                    attachment.setTime(time);
                    attachmentList.add(attachment);
                }
            }
            json.setObj(attachmentList);
            json.setFlag(0);
            json.setMsg("OK");

        } catch (Exception e) {
            L.e("findworkUpload" + e);
            json.setFlag(1);
            json.setMsg("false");
        }
        return json;
    }

    @Override
    public ToJson<FlowRunFeedback> workfeedback(String content, String runId, String prcsId, String flowPrcs,
                                                String userId) {
        String editTime = DateFormat.getStrDate(new Date());//设置日期格式
        ToJson<FlowRunFeedback> toJson = new ToJson<FlowRunFeedback>();
      /*  String module = ModuleEnum.WORKFLOW.getName();
        List<Attachment> list= enclosureService.uploadReturn(files, company, module);
        StringBuffer attachmentId = new StringBuffer();
        StringBuffer attachmentName = new StringBuffer();
        for(Attachment attachment : list){
            attachmentId.append(attachment.getAid()).append("@").append(attachment.getYm()).append("_").append(attachment.getAttachId()).append(",");
            attachmentName.append(attachment.getAttachName()).append(",");
        }*/
        FlowRunFeedback flowRunFeedback = new FlowRunFeedback();
        flowRunFeedback.setContent(content);
        flowRunFeedback.setUserId(userId);
        flowRunFeedback.setPrcsId(Integer.parseInt(prcsId));
        flowRunFeedback.setFlowPrcs(Integer.parseInt(flowPrcs));
        flowRunFeedback.setRunId(Integer.parseInt(runId));
        flowRunFeedback.setEditTime(editTime);
        //flowRunFeedback.setAttachmentId(attachmentId.toString());
        //flowRunFeedback.setAttachmentName(attachmentName.toString());
        try {
            workFlowServiceContext.getFlowRunFeedbackMapper().insertSelective(flowRunFeedback);
            toJson.setObject(flowRunFeedback);
            toJson.setFlag(0);
            toJson.setMsg("OK");
        } catch (Exception e) {
            toJson.setMsg("false");
            toJson.setFlag(1);
            L.e("workfeedback" + e);
        }
        return toJson;
    }

    @Override
    public AjaxJson findworkfeedback(HttpServletRequest request, String runId, String prcsId, String flowPrcs, String userId, String company, String signlock, String PRCS_ID, String FLOW_PRCS) {
        AjaxJson ajaxJson = new AjaxJson();
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("prcsId", Integer.parseInt(prcsId));
            map.put("runId", Integer.parseInt(runId));
            map.put("flowPrcs", flowPrcs);
            map.put("userId", userId);
            FlowTypeModel flowTypeModel = workFlowServiceContext.getFlowTypeService().sfTbyrunId(Integer.parseInt(runId));
            String flowType = flowTypeModel.getFlowType();
            Integer flowId = flowTypeModel.getFlowId();
            Map tempMap = new HashMap();
            tempMap.put("run_id", runId);
            tempMap.put("flow_id", flowId);
            List<FlowRunFeedback> tempFlowRunFeedbackList = new ArrayList<FlowRunFeedback>();
            List list = new ArrayList();
            Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
            Users user = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
            if (PRCS_ID != null && !"".equals(PRCS_ID)) {
                tempMap.put("PRCS_ID", PRCS_ID);
                tempFlowRunFeedbackList = workMapper.selectPrcsIdFeedbackContent(tempMap);
                for (FlowRunFeedback tempFlowRunFeedback : tempFlowRunFeedbackList) {
                    Users users = usersMapper.findUsersByuserId(tempFlowRunFeedback.getUserId());
                    tempFlowRunFeedback.setUsers(users);
                    String endTime = tempFlowRunFeedback.getEditTime();
                    tempFlowRunFeedback.setEditTime(endTime.substring(0, endTime.length() - 2));
                    list.add(tempFlowRunFeedback);
                }
                ajaxJson.setObj(list);
                ajaxJson.setMsg("OK");
                ajaxJson.setFlag(true);
                return ajaxJson;
            } else if (FLOW_PRCS != null && !"".equals(FLOW_PRCS)) {
                tempMap.put("FLOW_PRCS", FLOW_PRCS);
                String[] fp = null;
                if (FLOW_PRCS.contains(",")) {
                    fp = FLOW_PRCS.split(",");
                } else {
                    fp = new String[1];
                    fp[0] = FLOW_PRCS;
                }
                tempMap.put("fps", fp);
                tempFlowRunFeedbackList = workMapper.selectPrcsIdFeedbackContent(tempMap);

                for (FlowRunFeedback tempFlowRunFeedback : tempFlowRunFeedbackList) {
                    Users users = usersMapper.findUsersByuserId(tempFlowRunFeedback.getUserId());
                    List<Department> l = departmentService.getFatherDept(users.getDeptId(), new ArrayList<Department>());
                    StringBuffer sb = new StringBuffer();
                    for (int i = l.size() - 1; i >= 0; i--) {
                        sb.append(l.get(i).getDeptName());
                        if (i > 0) {
                            sb.append("/");
                        }
                    }
                    tempFlowRunFeedback.setUsers(users);
                    tempFlowRunFeedback.setDeptName(users.getDeptName());
                    tempFlowRunFeedback.setLongDeptName(sb.toString());
                    String endTime = tempFlowRunFeedback.getEditTime();
                    tempFlowRunFeedback.setEditTime(endTime.substring(0, endTime.length() - 2));
                    list.add(tempFlowRunFeedback);
                }
                ajaxJson.setObj(list);
                ajaxJson.setMsg("OK");
                ajaxJson.setFlag(true);
                return ajaxJson;
            } else {
                //获取所有流程步骤
                List<FlowRunFeedback> modelList = this.selectFlowFeedBackByRunId(runId);
                //固定流程
                if (flowType.equals("1")) {
                    //获取该流程所有步骤
                    List<FlowProcess> allFp = workFlowServiceContext.getFlowProcessService().findFlowId(flowId);
                    for (FlowProcess flowProcess : allFp) {
                        //处理不是当前节点的会签可见性
                        if (!String.valueOf(flowProcess.getPrcsId()).equals(flowPrcs)) {
                            //针对其他步骤不可见
                            if (flowProcess.getSignlook().equals("2")) {
                                Iterator<FlowRunFeedback> it = modelList.iterator();
                                while (it != null && it.hasNext()) {
                                    FlowRunFeedback fbm = it.next();
                                    if (fbm.getFlowPrcs() == flowProcess.getPrcsId()) {
                                        it.remove();
                                    }
                                }
                            }
                        } else {//处理是当前节点的会签可见性
                            if (flowProcess.getSignlook().equals("1")) {//本步骤经办人之间不可见
                                Iterator<FlowRunFeedback> it = modelList.iterator();
                                while (it != null && it.hasNext()) {
                                    FlowRunFeedback fbm = it.next();
                                    if (fbm.getFlowPrcs() == flowProcess.getPrcsId() && fbm.getUserId() != userId) {
                                        it.remove();
                                    }
                                }
                            }
                        }
                    }
                }
                for (FlowRunFeedback flowRunFeedback : modelList) {
                    Users users = usersService.findUsersByuserId(flowRunFeedback.getUserId());
                    List<Department> l = departmentService.getFatherDept(users.getDeptId(), new ArrayList<Department>());
                    StringBuffer sb = new StringBuffer();
                    for (int i = l.size() - 1; i >= 0; i--) {
                        sb.append(l.get(i).getDeptName());
                        if (i > 0) {
                            sb.append("/");
                        }
                    }
                    flowRunFeedback.setUsers(users);
                    flowRunFeedback.setDeptName(users.getDeptName());
                    flowRunFeedback.setLongDeptName(sb.toString());
                    String editTime = flowRunFeedback.getEditTime().substring(0, flowRunFeedback.getEditTime().length() - 2);
                    flowRunFeedback.setEditTime(editTime);
                    flowRunFeedback.setUsers(users);
                }
                for (FlowRunFeedback flowRunFeedback : modelList) {
                    String u = flowRunFeedback.getUserId();
                    Users users = usersService.getUsersByuserId(u);
              /*  if (users.getAvatar().equals("0")){
                    users.setAvatar("../../img/user/girl.jpg");
                }
                if (users.getAvatar().equals("1")){
                    users.setAvatar("../../img/user/boy.jpg");
                }*/
                    flowRunFeedback.setUsers(users);
                }
                ajaxJson.setObj(modelList);
                ajaxJson.setMsg("OK");
                ajaxJson.setFlag(true);
            }
        } catch (Exception e) {
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("false");
        }
        return ajaxJson;
    }

    public List<FlowRunFeedback> selectFlowFeedBackByRunId(String runId) {
        FlowTypeModel flowTypeModel = workFlowServiceContext.getFlowTypeService().sfTbyrunId(Integer.parseInt(runId));
        String flowType = flowTypeModel.getFlowType();
        Integer flowId = flowTypeModel.getFlowId();
        List<FlowRunFeedback> list = new ArrayList<FlowRunFeedback>();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", Integer.parseInt(runId));
        //如果是自由流程
        if (flowType.equals("2")) {
            list = workFlowServiceContext.getFlowRunFeedbackMapper().selectRunId(map);
        } else {
            list = workFlowServiceContext.getFlowRunFeedbackMapper().selectFeedBackByRunId(map);
        }
        return list;
    }

    //    @RequestParam(value="formdata",required = false) String formdata,
//    @RequestParam(value="modifydata",required = false) String modifydata,
//    @RequestParam(value="formLength",required = false) String formlength,
    //并发
    @Override
    public ToJson<FlowRunPrcs> savework(String runId, String runName, String flowId, String prcsId, String prcsFlag,
                                        String flowPrcs, String beginTime, String beginUser, String jingbanUser, String viewUser, Users users, String currentPrcsId) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("prcsId", Integer.parseInt(prcsId));
        maps.put("runId", Integer.parseInt(runId));
        maps.put("prcsFlag", "3");
        maps.put("deliverTime", DateFormat.getStrDate(new Date()));
        maps.put("userId", users.getUserId());
        //应对并发
        if (!flowPrcs.contains(",")) {
            maps.put("flowPrcs", currentPrcsId);
        }
        workFlowServiceContext.getFlowRunPrcsService().updateSql(maps);
        FlowRunPrcs fl = new FlowRunPrcs();
        if (flowPrcs.equals("0")) {
            // 添加传阅
            FlowRun flowRun = flowRunMapper.selectByPrimaryKey(Integer.valueOf(runId));
            if (flowRun != null) {
                if (!StringUtils.checkNull(viewUser)) {
                    //修改传阅人
                    flowRun.setViewUser(viewUser);
                    flowRunMapper.updateByPrimaryKeySelective(flowRun);
                }
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("endTime", DateFormat.getStrDate(new Date()));
            map.put("runId", runId);
            workFlowServiceContext.getFlowRunService().updateTime(map);
            Map<String, Object> updateSatus = new HashMap<String, Object>();
            updateSatus.put("prcsId", prcsId);
            updateSatus.put("runId", runId);
            updateSatus.put("prcsFlag", "4");
            updateSatus.put("userId", users.getUserId());
            workFlowServiceContext.getFlowRunPrcsService().updateSql(updateSatus);
            try {
                toJson.setObject(fl);
                toJson.setMsg("OK");
                toJson.setFlag(0);
            } catch (Exception e) {
                toJson.setMsg(e.getMessage());
                L.e("work saveWork:" + e);
            }
            return toJson;
        }
        String[] fpArray = flowPrcs.split(",");
        String[] alljingbanArray = jingbanUser.split("\\|");
        String[] beginUserArray = beginUser.split(",");
        for (int i = 0; i < fpArray.length; i++) {
            String[] jingbanArray = null;
            jingbanArray = alljingbanArray[i].split(",");
            String beginByUser = beginUserArray[i];
            for (int j = 0; j < jingbanArray.length; j++) {
                fl = new FlowRunPrcs();
                if (beginByUser.equals(jingbanArray[j])) {
                    fl.setOpFlag("1");
                } else {
                    fl.setOpFlag("0");
                }
                fl.setTopFlag("0");
                fl.setRunId(Integer.parseInt(runId));
                fl.setPrcsId(Integer.parseInt(prcsId) + 1);
                fl.setPrcsFlag("1");
                fl.setFlowPrcs(Integer.parseInt(fpArray[i]));
                fl.setUserId(jingbanArray[j]);
                fl.setCreateTime(DateFormat.getStrDate(new Date()));
                fl.setPrcsTime("2000-01-01 00:00:00");
                fl.setDeliverTime("2000-01-01 00:00:00");
                fl.setActiveTime("2000-01-01 00:00:00");
                fl.setParent(currentPrcsId);
                workFlowServiceContext.getFlowRunPrcsService().save(fl);
            }

        }
        try {
            toJson.setMsg("OK");
            toJson.setFlag(0);
        } catch (Exception e) {
            toJson.setMsg(e.getMessage());
        }
        return toJson;
    }

    @Override
    public ToJson<FlowRunPrcs> getflowprcsdata(String allowBack, String runId, String prcsId) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        Map<String, Object> m = new HashMap<String, Object>();
        try {
            switch (Integer.parseInt(allowBack)) {
                case 1:
                    m.put("prcsId", Integer.parseInt(prcsId) - 1);
                    m.put("runId", runId);
                    List<FlowRunPrcs> listFloRunPrcs = workFlowServiceContext.getFlowRunPrcsService().findByRunId(m);
                    toJson.setObj(listFloRunPrcs);
                    toJson.setMsg("true");
                    toJson.setFlag(0);
                    return toJson;
                case 2:
                    m.put("prcsId", prcsId);
                    m.put("runId", runId);
                    List<FlowRunPrcs> list = workFlowServiceContext.getFlowRunPrcsService().findlessRunId(m);
                    toJson.setObj(list);
                    toJson.setFlag(0);
                    toJson.setMsg("true");
                    return toJson;
            }
        } catch (Exception e) {
            L.e("getflowprcsdate" + e.getMessage());
            toJson.setFlag(1);
            toJson.setMsg("false");
            return toJson;
        }
        toJson.setFlag(0);
        toJson.setMsg("true");
        return toJson;
    }


    private static String document = "document";
    private static String attend_leave = "attend_leave";
    private static String attend_evection = "attend_evection";
    private static String attend_out = "attend_out";
    private static String addNotify = "save_notify";
    private static String fileContent = "save_fileContent";

    /**
     * 创建作者:   张勇
     * 创建日期:   2017/6/22 16:26
     * 方法介绍:
     * 参数说明:   formmat 公告通知格式(0-普通格式,1-MHT格式,2-超链接),默认为0
     * 参数说明:   userId 按人员发布（公告）
     * 参数说明:   fromId 发送人
     * 参数说明:   sendTime 发送时间（目前只适用于公告，邮件等为时间戳的需要转换）
     * 参数说明:   subject 标题
     * 参数说明:  count 内容
     * 参数说明:  toId2 收件人
     * 参数说明:  flowId 流程Id
     * 参数说明:  flowPrcs 步骤Id
     *
     * @return
     */
    public ToJson notifyNotice(TriggerPlugIn triggerPlugIn) {
        ToJson<FlowFast> FlowFast = workFastAdd(triggerPlugIn.getUsers(), Integer.parseInt(triggerPlugIn.getFlowId()), Integer.parseInt(triggerPlugIn.getPrcsId()), triggerPlugIn.getFlowPrcs(), triggerPlugIn.getRunId(), triggerPlugIn.getRequest()
                , triggerPlugIn.getSqlType(), triggerPlugIn.getRunName(), null);
        triggerPlugIn.setFlowFast((FlowFast) FlowFast.getObject());
        ToJson toJson = new ToJson(1, "error");
        try {
            List<FlowTiggerModel> list = flowTiggerMapper.selectFlowTigger(Integer.parseInt(triggerPlugIn.getFlowId()), Integer.parseInt(triggerPlugIn.getFlowPrcs()));
            if (list != null && list.size() > 0) {
                for (int i = 0, len = list.size(); i < len; i++) {
                    // triggerPlugIn.setHookId(list.get(i).getBusinessLogicId());
                    if (triggerPlugIn.getFlag().equals(list.get(i).getPluginType()) && 1 == list.get(i).getActived()) {
                        if (list.get(i).getPlugin() != 0 && list.get(i).getBusinessLogicId() != 0) {//判断插件和业务引擎接口都在
                            triggerPlugIn.setDistinguish("1");
                            FlowPluginModel flowPluginModel = flowPluginMapper.selectList(list.get(i).getPlugin());
                            FlowHookWithBLOBs flowHook = new FlowHookWithBLOBs();
                            flowHook.setHid(list.get(i).getBusinessLogicId());
                            FlowHookWithBLOBs flowHook1 = flowHookMapper.selectByhid(flowHook);
                            if (flowHook1 != null) {
                                triggerPlugIn.setHookId(flowHook1.getHid());
                                if (document.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("DocumentTrigger");
                                } else if (attend_leave.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendLeaveTrigger");
                                } else if (attend_evection.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendEvectionTrigger");
                                } else if (attend_out.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendOutTrigger");
                                }else if (addNotify.equals(flowHook1.getHmodule())) {
                                    Notify notify = new Notify();
                                    notify.setOpinUsers("");
                                    notify.setOpinionFields("");
                                    notifyMapper.addNotify(notify);
                                    triggerPlugIn.setNotifyId(notify.getNotifyId());
                                    flowHook1.setHmodule("NotifyTrigger");
                                }else if (fileContent.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("SaveFileContent");
                                }
                                Trigger.run("com.xoa.plugin." + flowHook1.getHmodule(), triggerPlugIn.getSqlType(), triggerPlugIn);
                            }

                            inTigger(flowPluginModel.getFlowPluginFlag(), flowPluginModel.getFlowPluginModel(), triggerPlugIn);

                        } else if (list.get(i).getPlugin() != 0) {//判断插件在
                            FlowPluginModel flowPluginModel = flowPluginMapper.selectList(list.get(i).getPlugin());
                            triggerPlugIn.setDistinguish("1");
                            inTigger(flowPluginModel.getFlowPluginFlag(), flowPluginModel.getFlowPluginModel(), triggerPlugIn);
                        } else if (list.get(i).getBusinessLogicId() != 0) {//判断业务引擎接口在
                            FlowHookWithBLOBs flowHook = new FlowHookWithBLOBs();
                            flowHook.setHid(list.get(i).getBusinessLogicId());
                            FlowHookWithBLOBs flowHook1 = flowHookMapper.selectByhid(flowHook);
                            if (flowHook1 != null) {
                                triggerPlugIn.setDistinguish("1");
                                triggerPlugIn.setHookId(flowHook1.getHid());
                                if (document.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("DocumentTrigger");
                                } else if (attend_leave.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendLeaveTrigger");
                                } else if (attend_evection.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendEvectionTrigger");
                                } else if (attend_out.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("AttendOutTrigger");
                                }else if (addNotify.equals(flowHook1.getHmodule())) {
                                    Notify notify = new Notify();
                                    notify.setOpinUsers("");
                                    notify.setOpinionFields("");
                                    notifyMapper.addNotify(notify);
                                    triggerPlugIn.setNotifyId(notify.getNotifyId());
                                    flowHook1.setHmodule("NotifyTrigger");
                                }else if (fileContent.equals(flowHook1.getHmodule())) {
                                    flowHook1.setHmodule("SaveFileContent");
                                }
                                Trigger.run("com.xoa.plugin." + flowHook1.getHmodule(), triggerPlugIn.getSqlType(), triggerPlugIn);
                            }
                        }
                    } else {
                        toJson.setFlag(0);
                        toJson.setMsg("ok");
                    }
                }
            } else {
                if (!StringUtils.checkNull(triggerPlugIn.getTableName())) {

                    if ("document".equals(triggerPlugIn.getTableName())) {
                        triggerPlugIn.setDistinguish("1");
                        Trigger.run("com.xoa.plugin.DocumentTrigger", triggerPlugIn.getSqlType(), triggerPlugIn);
                    }


                }


            }
        } catch (Exception e) {
            L.e("workFlowServiceContext.getFlowRunPrcsService()Impl notifyNotice:" + e);
        }
        return toJson;
    }

    /**
     * 创建作者:   张龙飞
     * 创建日期:   2017年6月25日 上午10:31:07
     * 方法介绍:   选人过滤规则判断
     * 参数说明:   @param userFilter 过滤规则
     * 参数说明:   @param users   用户信息
     * 参数说明:   @return
     *
     * @return List<Users>
     */
    public List<Users> userFilterlist(Integer userFilter, Users users, FlowProcess flowProcess) {
        List<Users> userFilterlist = null;
        switch (userFilter) {
            case 1://只允许本部门
                userFilterlist = usersService.getUsersByDeptId(users.getDeptId());
                return userFilterlist;
            case 2://只允许本角色
                userFilterlist = usersService.getUserByDeptIds(String.valueOf(users.getUserPriv()), 2);
                return userFilterlist;
            case 3://只允许选择上级部门
                userFilterlist = usersService.getPUsersByDeptId(users.getDeptId());
                return userFilterlist;
            case 4://只允许选择下级部门
                userFilterlist = usersService.getCUsersByDeptId(users.getDeptId());
                return userFilterlist;
            case 5://同级部门
                userFilterlist = usersService.getTUsersByDeptId(users.getDeptId());
                return userFilterlist;
            case 6://指定部门
                userFilterlist = usersService.getUserByDeptIds(flowProcess.getUserFilterPrcsDept(), 1);
                return userFilterlist;
            case 7://指定角色
                userFilterlist = usersService.getUserByDeptIds(flowProcess.getUserFilterPrcsPriv(), 2);
                return userFilterlist;
            case 8://本辅助部门
                userFilterlist = usersService.getUserByDeptIds(users.getDeptIdOther(), 1);
                return userFilterlist;
            case 9://指定辅助部门
                userFilterlist = usersService.getUserByDeptIds(flowProcess.getUserFilterPrcsDeptOther(), 3);
                return userFilterlist;
            case 10://本辅助角色
                userFilterlist = usersService.getUserByDeptIds(users.getUserPrivOther(), 2);
                return userFilterlist;
            case 11://指定辅助角色
                userFilterlist = usersService.getUserByDeptIds(users.getUserPrivOther(), 4);
                return userFilterlist;
            case 12://本部门和下级部门
                userFilterlist = usersService.getUsersByDeptId(users.getDeptId());
                userFilterlist.addAll(usersService.getCUsersByDeptId(users.getDeptId()));
                return userFilterlist;
            default:
                return userFilterlist;
        }
    }

    /**
     * 创建作者:   张龙飞
     * 创建日期:   2017年6月25日 上午10:31:07
     * 方法介绍:   自动选人规则
     * 参数说明:   @param autoType 选人
     * 参数说明:   @param users   用户信息
     * 参数说明:   @param dep  部门信息
     * 参数说明:   @return
     *
     * @return List<Users>
     */
    public List<Users> autoTypelist(Integer autoType, Department dep, Users users, String runId, FlowProcess flowProcess) {
        List<Users> autoTypelist = new ArrayList<Users>();
        switch (autoType) {
            case 1://自动选择流程发起人
                FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(runId));
                Users u = usersService.findUsersByuserId(flowRun.getBeginUser());
                autoTypelist.add(u);
                return autoTypelist;
            case 2://自动选择部门主管人
                autoTypelist = usersService.getUserByuId(dep.getManager());
                return autoTypelist;
            case 3://自动选择默认人员
                autoTypelist = usersService.getUserByuId(dep.getManager());
                return autoTypelist;
            case 4://自动选择上级主管领导
                autoTypelist = usersService.getUserByuId(dep.getLeader1());
                return autoTypelist;
            case 5://自动选择一级部门主管
                autoTypelist = usersService.getUserByuId(dep.getManager());
                return autoTypelist;
            case 6://自动选择上级分管主管
                autoTypelist = usersService.getUserByuId(dep.getLeader2());
                return autoTypelist;
            case 7://按表单字段选择
                String autoUser = flowProcess.getAutoUser();
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("tableName", "flow_data_" + flowProcess.getFlowId());
                map.put("runId", runId);
                Map<String, Object> maps = workFlowServiceContext.getWorkMapper().select(map);
                if (maps != null) {
                    String userName = (String) maps.get(autoUser);
                    Users users1 = usersService.getUserByUserName(userName);
                    if (users1 != null) {
                        autoTypelist.add(users1);
                    }
                }
                return autoTypelist;
            case 8://指定步骤主办人
                return autoTypelist;
            case 9://自动选择本部门助理
                autoTypelist = usersService.getUserByuId(dep.getAssistantId());
                return autoTypelist;
            case 10://自动选择本部门内符合条件所有人
                //  return autoTypelist;
            case 11://自动选择本一级部门内符合条件所有人员
                // return autoTypelist;
            case 12://自动选择指定部门主管
                return autoTypelist;
            case 13://自动选择指定部门助理
                return autoTypelist;
            case 14://自动选择指定部门上级主管领导
                return autoTypelist;
            case 15://自动选择指定部门上级分管领导
                return autoTypelist;
            default:
                return autoTypelist;
        }
    }

    public List<Users> allUserlist(List<Users> userFilterlist, List<Users> prcsUserlist, List<Users> prcsDeptlist, List<Users> prcsPrivlist) {
        List<Users> allUser = new ArrayList<Users>();
        if (prcsUserlist != null) {
            allUser.addAll(prcsUserlist);
        }
        if (prcsDeptlist != null) {
            allUser.addAll(prcsDeptlist);
        }
        if (prcsPrivlist != null) {
            allUser.addAll(prcsPrivlist);
        }
        if (allUser != null) {
            for (Users users : allUser) {
                for (Users users1 : userFilterlist) {
                    if (users.getUid() == users1.getUid()) {
                        allUser.remove(users);
                    }
                }
            }
        }
        return allUser;
    }

    @Override
    public AjaxJson insertprcsdata(String runId, String flowStep, String prcsId, String flowPrcs, Users users, String feedback) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, Object> maps = new HashMap<String, Object>();
        try {
            maps.put("prcsId", flowStep);
            maps.put("runId", runId);
            maps.put("prcsFlag", "3");
            maps.put("deliverTime", DateFormat.getStrDate(new Date()));
            workFlowServiceContext.getFlowRunPrcsService().updateSql(maps);
            maps.put("prcsId", flowPrcs);
            List<FlowRunPrcs> listFloRunPrcs = workFlowServiceContext.getFlowRunPrcsService().findByRunId(maps);
            FlowRunPrcs fp = listFloRunPrcs.get(0);

            FlowRunPrcs flowRunPrcs = new FlowRunPrcs();
            flowRunPrcs.setRunId(Integer.parseInt(runId));
            //flowRunPrcs.setPrcsId(flowProcess.getPrcsId());
            flowRunPrcs.setPrcsId(Integer.parseInt(flowStep) + 1);
            flowRunPrcs.setUserId(fp.getUserId());
            flowRunPrcs.setPrcsDept(users.getDeptId());
            flowRunPrcs.setPrcsFlag("1");
            flowRunPrcs.setFlowPrcs(fp.getFlowPrcs());
            flowRunPrcs.setOpFlag("1");
            flowRunPrcs.setTopFlag("0");
            flowRunPrcs.setCreateTime(DateFormat.getStrDate(new Date()));
            flowRunPrcs.setPrcsTime(DateFormat.getStrDate(new Date()));
            flowRunPrcs.setDeliverTime("2000-01-01 00:00:00");
            flowRunPrcs.setActiveTime("2000-01-01 00:00:00");
            flowRunPrcs.setBackFlowPrcs(fp.getFlowPrcs());
            flowRunPrcs.setBackPrcsId(fp.getPrcsId());
            flowRunPrcs.setParent(String.valueOf(fp.getFlowPrcs()));
            workFlowServiceContext.getFlowRunPrcsService().save(flowRunPrcs);
            ToJson<FlowRunFeedback> json = this.workfeedback(feedback, runId, flowStep, String.valueOf(fp.getFlowPrcs()), users.getUserId());
            ajaxJson.setObj(flowRunPrcs);
            ajaxJson.setMsg("true");
            ajaxJson.setFlag(true);
        } catch (Exception e) {
            L.e("insertprcsDate" + e.getMessage());
            ajaxJson.setMsg("false");
            ajaxJson.setFlag(false);
        }
        return ajaxJson;
    }


    @Override
    public AjaxJson findBranch(String flowId, String runId, String flowPrcs, Users users) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, FlowFast> mAll = new HashMap<String, FlowFast>();
        try {
            String[] fpArray = flowPrcs.split(",");
            for (int j = 0; j < fpArray.length; j++) {
                if (!fpArray[j].equals("0")) {
                    //获取所有流程实例信息
                    List<FlowProcess> allFp = workFlowServiceContext.getFlowProcessService().findFlowId(Integer.parseInt(flowId));
                    //定义map集合存储所有的流程实例，并根据flowPrcs获取
                    Map<String, FlowProcess> map = new HashMap<String, FlowProcess>();
                    for (int i = 0; i < allFp.size(); i++) {
                        FlowProcess flowProcess = allFp.get(i);
                        map.put(String.valueOf(flowProcess.getPrcsId()), flowProcess);
                    }
                    FlowProcess flowProcess = map.get(fpArray[j]);

                    FlowFast flowFast = new FlowFast();
                    //本部门
                    Department dep = departmentService.getDeptById(users.getDeptId());

                    //选人过滤规则
                    String uF = flowProcess.getUserFilter();
                    //选人过滤规则
                    List<Users> userFilterlist = new ArrayList<Users>();
                    //选人过滤规则判断
                    if (flowProcess.getUserFilter() != "") {
                        Integer userFilter = Integer.parseInt(flowProcess.getUserFilter());
                        userFilterlist = this.userFilterlist(userFilter, users, flowProcess);
                    }
                    //存储所有忽略规则的map（用于遍历移除）
                    Map<Integer, Object> map1 = new HashMap<Integer, Object>();
                    for (Users u : userFilterlist) {
                        map1.put(u.getUid(), u);
                    }

                    //自动选人规则
                    String aT = flowProcess.getAutoType();
                    List<Users> autoTypelist = null;
                    if (aT != "") {
                        Integer autoType = Integer.parseInt(aT);
                        autoTypelist = this.autoTypelist(autoType, dep, users, runId, flowProcess);
                    }

                    flowFast.setUserFilter(uF);
                    flowFast.setUserFilterlist(userFilterlist);
                    flowFast.setAutoType(aT);
                    flowFast.setAutoTypelist(autoTypelist);

                    //经办人串
                    String prcsUser = flowProcess.getPrcsUser();
                    //用来存储经办人信息
                    List<Users> prcsUserlist = null;
                    List<Users> prcsUserlistfilter = new ArrayList<Users>();
                    if (prcsUser != "") {
                        flowFast.setPrcsUser(prcsUser);
                        //查询所有符合条件经办人信息集合
                        prcsUserlist = usersService.getUserByuserId(flowProcess.getPrcsUser());
                        //迭代器遍历删除符合过滤条件的对象
                        Iterator<Users> it = prcsUserlist.iterator();
                        while (it.hasNext()) {
                            Users u = it.next();
                            if (map1.containsKey(u.getUid())) {
                                it.remove();
                            }
                        }
                        flowFast.setPrcsUserlist(prcsUserlist);
                    } else {
                        flowFast.setPrcsUser(prcsUser);
                        flowFast.setPrcsUserlist(prcsUserlist);
                    }
                    //经办人部门id串
                    String prcsDept = flowProcess.getPrcsDept();
                    List<Users> prcsDeptlist = null;
                    List<Users> prcsDeptlistFifter = new ArrayList<Users>();
                    if (!"ALL_DEPT".trim().equals(prcsDept)) {
                        flowFast.setPrcsDept(prcsDept);
                        prcsDeptlist = usersService.getUserByDeptIds(prcsDept, 1);
                        if (prcsDeptlist != null) {

                            //迭代器遍历删除符合过滤条件的对象
                            Iterator<Users> it = prcsDeptlist.iterator();
                            while (it.hasNext()) {
                                Users u = it.next();
                                if (map1.containsKey(u.getUid())) {
                                    it.remove();
                                }
                            }
                            flowFast.setPrcsDeptlist(prcsDeptlist);
                        }
                    } else {
                        flowFast.setPrcsDept(prcsDept);
                        flowFast.setPrcsDeptlist(prcsDeptlist);
                    }
                    //经办角色id串
                    String prcsPriv = flowProcess.getPrcsPriv();
                    List<Users> prcsPrivlist = null;
                    List<Users> prcsPrivlistFifter = new ArrayList<Users>();
                    if (prcsPriv != "" && prcsPriv != null) {
                        flowFast.setPrcsPriv(prcsPriv);
                        prcsPrivlist = usersService.getUserByDeptIds(prcsPriv, 2);
                        if (prcsPrivlist != null) {

                            //迭代器遍历删除符合过滤条件的对象
                            Iterator<Users> it = prcsPrivlist.iterator();
                            while (it.hasNext()) {
                                Users u = it.next();
                                if (map1.containsKey(u.getUid())) {
                                    it.remove();
                                }
                            }
                            flowFast.setPrcsPrivlist(prcsPrivlist);
                        }
                    } else {
                        flowFast.setPrcsPriv(prcsPriv);
                        flowFast.setPrcsPrivlist(prcsPrivlist);
                    }


                    Map<String, Users> m = new HashMap<String, Users>();
                    if (prcsUserlist != null && prcsUserlist.size() > 0) {
                        for (Users u1 : prcsUserlist) {
                            m.put(u1.getUserId(), u1);
                        }
                    }
                    if (prcsDeptlist != null && prcsDeptlist.size() > 0) {
                        for (Users u2 : prcsDeptlist) {
                            m.put(u2.getUserId(), u2);
                        }
                    }
                    if (prcsPrivlist != null && prcsPrivlist.size() > 0) {
                        for (Users u3 : prcsPrivlist) {
                            m.put(u3.getUserId(), u3);
                        }
                    }
                    List<Users> l = new ArrayList<Users>(m.values());
                    flowFast.setPrcsUserlist(l);
                    mAll.put(fpArray[j], flowFast);
                }
            }
            ajaxJson.setObj(mAll);
            ajaxJson.setFlag(true);
            ajaxJson.setMsg("OK");
        } catch (Exception e) {
            L.e("findBranch" + e);
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("false");
            return ajaxJson;
        }
        return ajaxJson;
    }

    @Override
    public ToJson delete(String runId,
                         @RequestParam("AID") String aid,
                         @RequestParam("MODULE") String module,
                         @RequestParam("YM") String ym,
                         @RequestParam("ATTACHMENT_ID") String attachmentId,
                         @RequestParam("ATTACHMENT_NAME") String attachmentName,
                         @RequestParam("COMPANY") String company,
                         HttpServletResponse response,
                         HttpServletRequest request) {
        ToJson tj = new ToJson();
        try {
            FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(runId));
            StringBuffer id = new StringBuffer();
            StringBuffer name = new StringBuffer();
            tj = enclosureService.delete(aid, module, ym, attachmentId, attachmentName, company, response, request);
            if (tj.isFlag()) {
                if (flowRun.getAttachmentId() != "" || flowRun.getAttachmentName() != "") {
                    String[] attachmentIds = flowRun.getAttachmentId().split(",");
                    String[] attachName = flowRun.getAttachmentName().split("\\*");
                    List<String> idsList = new ArrayList<String>();
                    Collections.addAll(idsList, attachmentIds);
                    List<String> nameList = new ArrayList<String>();
                    Collections.addAll(nameList, attachName);
                    for (int i = 0; i < attachmentIds.length; i++) {
                        String yaid = attachmentIds[i].substring(0, attachmentIds[i].indexOf('@'));
                        if (yaid.equals(aid)) {
                            idsList.remove(attachmentIds[i]);
                            attachmentIds = idsList.toArray(new String[0]);
                            break;
                        }
                    }
                    for (int j = 0; j < attachName.length; j++) {
                        String yattachName = attachName[j];
                        if (yattachName.equals(attachmentName)) {
                            nameList.remove(attachName[j]);
                            attachName = nameList.toArray(new String[0]);
                            break;
                        }
                    }

                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("runId", runId);
                    map.put("attachmentId", org.apache.commons.lang3.StringUtils.join(attachmentIds, ","));
                    map.put("attachmentName", org.apache.commons.lang3.StringUtils.join(attachName, "*"));
                    workFlowServiceContext.getFlowRunService().updateAttachment(map);
                }
                tj.setFlag(0);
                tj.setMsg("true");
                return tj;
            }
            tj.setFlag(1);
            tj.setMsg("false");
            return tj;
        } catch (Exception e) {
            L.e("delete" + e);
            tj.setFlag(1);
            tj.setMsg("false");
            return tj;
        }
    }


    /**
     * 创建作者:   张勇
     * 创建日期:   2017/7/4 12:54
     * 方法介绍:   内部触发器插件工具类
     * 参数说明:
     *
     * @return
     */
    private void inTigger(Integer flag, String flags, TriggerPlugIn tri) {
        ToJson toJson = new ToJson(1, "error");
        // Trigger.run("com.xoa.plugin."+flags,tri);
        switch (flag) {
            case BUILT_IN:
                Trigger.run("com.xoa.plugin." + flags, tri.getSqlType(), tri);
            case BUILT_OUT:
//                                userFilterlist = workFlowServiceContext.getUsersService.getUserByDeptIds(String.valueOf(users.getUserPriv()), 2);
//                                return userFilterlist;

            case BUILT_PUSH:
//                                userFilterlist = workFlowServiceContext.getUsersService.getPUsersByDeptId(users.getDeptId());
//                                return userFilterlist;

            default:


        }

    }

    private ToJson outTigger(String flags, String format, String fromId, Date sendTime, String subject, String content, String toId2) {
        ToJson toJson = new ToJson(1, "error");


        return toJson;
    }

    /**
     * 内置
     */
    private final int BUILT_IN = 0;
    /**
     * 对外接口获取数据
     */
    private final int BUILT_OUT = 1;
    /**
     * 数据推送对方接口
     */
    private final int BUILT_PUSH = 2;

    /**
     * 新建操作
     */
    private static int create = 1;

    /**
     * 接收操作
     */
    private static int receive = 2;

    /**
     * 保存操作
     */
    private static int save = 3;

    /**
     * 转交操作
     */
    private static int turn = 4;

    /**
     * 委托操作
     */
    private static int intrust = 5;

    /**
     * 退回操作
     */
    private static int back = 6;

    /**
     * 创建作者:   张勇
     * 创建日期:   2017/7/12 13:44
     * 方法介绍:   触发器类型判断
     * CREATE 新建操作  key: 1
     * RECEIVE 接收操作 key: 2
     * SAVE 保存操作   key: 3
     * TURN 转交操作   key: 4
     * INTRUST 委托操作  key: 5
     * BACK 退回操作    key: 6
     * 参数说明:
     *
     * @return
     */
    public Map<Integer, String> returnMap() {
        Map<Integer, String> maps = new HashMap<Integer, String>();
        maps.put(1, "CREATE");
        maps.put(2, "RECEIVE");
        maps.put(3, "SAVE");
        maps.put(4, "TURN");
        maps.put(5, "INTRUST");
        maps.put(6, "BACK");
        return maps;
    }

    public Map<Object, Object> queryTriggerField(String modifydata, String fromdate, String maps) {

        //获取json串 进行判断
        //获取业务引擎接口的数据进行分开，组合map
        /**
         * 拿自己内置的数据去写的
         */

        String[] a = maps.split(",");
        Map<String, Object> map = new HashMap<String, Object>();
        for (int i = 0; i < a.length; i++) {
            String i1 = a[i];
            String i2[] = i1.split("=>");
            String i3 = i2[0];
            String i4 = i2[1];
            map.put(i3, i4);
        }
        JSONArray json = new JSONArray();
        //String fromdateOne="["+fromdate+"]";
        Map<String, Object> from = json.parseObject(
                fromdate, new TypeReference<Map<String, Object>>() {
                });


        List<Map<String, Object>> modify = json.parseObject(modifydata, List.class);
        //List<Map<String, Object>> from = json.parseObject(fromdate, List.class);
        Map<Object, Object> analysis = new HashMap<Object, Object>();
        Map<Object, Object> returnMap = new HashMap<Object, Object>();
        for (Map<String, Object> mapmodify : modify) {
            for (Map.Entry<String, Object> entry1 : from.entrySet()) {
                if (mapmodify.get("key").equals(entry1.getValue())) {
                    analysis.put(entry1.getKey(), mapmodify.get("value"));
                }

            }
        }
        for (Map.Entry<Object, Object> entry : analysis.entrySet()) {
            for (Map.Entry<String, Object> entry1 : map.entrySet()) {
                if (entry.getKey().equals(entry1.getValue())) {
                    returnMap.put(entry1.getKey(), entry.getValue());

                }

            }

        }


        return returnMap;
    }

    //获取表单设置
    public FlowFast getWorkFromSetting(int flowId) {
        FlowFast flowFast = new FlowFast();
        //获取工作流表单的样式
        //表单类型
        FlowTypeModel flowTypeModel = (FlowTypeModel) workFlowServiceContext.getFlowTypeService().selectAllFlow(flowId).getObject();
        //表单样式
        FlowFormType flowFormType = (FlowFormType) workFlowServiceContext.getFlowFormTypeService().qureyItemMax(flowTypeModel.getFormId()).getObject();
        flowFast.setFlowTypeModel(flowTypeModel);
        flowFast.setFlowFormType(flowFormType);
        return flowFast;
    }

    //转入和转出条件判断
    public FlowFast conditionSetting(FlowFast flowFast, int flowId, String flowPrcs) {
        //获取所有的流程步骤
        List<FlowProcess> allFp = workFlowServiceContext.getFlowProcessService().findFlowId(flowId);
        //根据对应条件遍历流程步骤过滤
        Map<String, FlowProcess> map = this.allflowProcessBymap(allFp);
        FlowProcess flowProcess = map.get(flowPrcs);
        FlowProcess nextfp = null;
        if (!flowProcess.getPrcsTo().equals("0,") && !flowProcess.getPrcsTo().equals("")) {
            String[] a = flowProcess.getPrcsTo().split(",");
            String b = a[0];
            nextfp = map.get(b);
            //转入串
            String prcsIn = nextfp.getPrcsIn();
            //转入逻辑表达式
            String prcsInSet = nextfp.getPrcsInSet();
            flowFast.setPrcsIn(prcsIn);
            flowFast.setPrcsInSet(prcsInSet);
            flowFast.setConditionDesc(flowProcess.getConditionDesc());
        }
        //转出串
        String prcsOut = flowProcess.getPrcsOut();
        //转出逻辑表达式
        String prcsOutSet = flowProcess.getPrcsOutSet();
        flowFast.setPrcsOut(prcsOut);
        flowFast.setPrcsOutSet(prcsOutSet);

        flowFast.setPrcsItem(flowProcess.getPrcsItem());
        flowFast.setRequiredItem(flowProcess.getRequiredItem());
        flowFast.setHiddenItem(flowProcess.getHiddenItem());

        String signlock = flowProcess.getSignlook();
        flowFast.setSignlock(signlock);
        //是否允许回退
        String allowBack = flowProcess.getAllowBack();
        flowFast.setAllowBack(allowBack);
        flowFast.setListFp(allFp);
        return flowFast;
    }

    //公共附件中的Office文档详细权限设置：(1-新建权限,2-编辑权限,3-删除权限,4-下载权限,5-打印权限,)
    public String attachPriv(FlowProcess flowProcess) {
        String item[] = flowProcess.getPrcsItem().split(",");
        for (String s : item) {
            if (s.equals(Constant.attach)) {
                return flowProcess.getAttachPriv();
            } else {
                return "";
            }
        }
        return "";
    }

    @Override
    @Transactional
    public ToJson<FlowFast> workFastAdd(Users users, int flowId, int prcsId, String flowPrcs, String id, HttpServletRequest request, String sqlType, String runName, String preView) {
        ToJson<FlowFast> tj = new ToJson<FlowFast>();
        try {
            //本部门
            Department dep = departmentService.getDeptById(users.getDeptId());
            //获取工作流表单的样式
            FlowFast flowFast = this.getWorkFromSetting(flowId);
            //获取当前流程的转入和转出的条件判断以及回退条件判断
            flowFast = this.conditionSetting(flowFast, flowId, flowPrcs);
            //存储所有流程信息
            Map<String, FlowProcess> map = this.allflowProcessBymap(flowFast.getListFp());


            FlowProcess flowProcess = map.get(flowPrcs);
            flowFast.setFlowProcesses(flowProcess);

            //判断是否允许传阅
            String isViewPriv = this.checkViewPriv(flowFast.getFlowTypeModel().getViewPriv(), flowProcess.getViewPriv());
            flowFast.setIsViewPriv(isViewPriv);
            List<Users> listView = new ArrayList<Users>();
            //可传阅用户
            if (isViewPriv.equals("1")) {
                listView = usersService.reAllPrivUser(flowFast.getFlowTypeModel().getViewUser(), flowFast.getFlowTypeModel().getViewDept(), flowFast.getFlowTypeModel().getViewRole());
                flowFast.setListView(listView);
            }
            String viewUser = usersService.reAllName(listView);


            String flowName = flowFast.getFlowTypeModel().getFlowName();
            String autoName = flowFast.getFlowTypeModel().getAutoName();

            if (StringUtils.checkNull(runName)) {
                if (autoName != "") {
                    // 判断是否是新建
                    if (StringUtils.checkNull(id)) {
                        runName = this.lexicalParse(autoName, flowFast.getFlowTypeModel(), users, dep);
                    }
                } else {
                    runName = flowFast.getFlowTypeModel().getFlowName() + " " + DateFormat.getStrDate(new Date());
                }
            }
            FlowRunPrcs flowRunPrcs = null;
            //适应前端查询请求,判断是否存在此流程
            Map<String, Object> mapCheck = new HashMap<String, Object>();
            mapCheck.put("prcsId", prcsId);
            mapCheck.put("runId", id);
            mapCheck.put("flowPrcs", flowPrcs);
            List<FlowRunPrcs> checkFloRunPrcs = workFlowServiceContext.getFlowRunPrcsService().findByRunId(mapCheck);
            if (checkFloRunPrcs.size() > 0) {
                for (FlowRunPrcs flowRunPrcs1 : checkFloRunPrcs) {
                    if (("1").equals(preView)) {
                        FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(id));
                        flowRun.setUserName(users.getUserName());
                        flowFast.setFlowRun(flowRun);
                        flowFast.setFlowRunPrcs(flowRunPrcs1);

                        String feedback = flowProcess.getFeedback();
                        flowFast.setFeedback(feedback);
                        flowFast.setAttachPriv(this.attachPriv(flowProcess));
                        //强制合并
                        //  Integer gatherNodePriv = this.reGatherNodePriv(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId);
                        Integer gatherNodePriv = this.findFlowPrcsProcess(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId, prcsId);
                        flowFast.setGatherNodePriv(String.valueOf(gatherNodePriv));

                        tj.setObject(flowFast);
                        tj.setMsg("只显示查询！");
                        tj.setFlag(0);
                        return tj;
                    }
                    if (users.getUserId().equals(flowRunPrcs1.getUserId())) {
                        if (Integer.parseInt(flowRunPrcs1.getPrcsFlag()) >= 3) {
                            FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(id));
                            flowRun.setUserName(users.getUserName());
                            flowFast.setFlowRun(flowRun);
                            flowFast.setFlowRunPrcs(flowRunPrcs1);
                            String feedback = flowProcess.getFeedback();
                            flowFast.setFeedback(feedback);
                            flowFast.setAttachPriv(this.attachPriv(flowProcess));
                            //强制合并
                            //  Integer gatherNodePriv = this.reGatherNodePriv(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId);
                            Integer gatherNodePriv = this.findFlowPrcsProcess(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId, prcsId);
                            flowFast.setGatherNodePriv(String.valueOf(gatherNodePriv));
                            tj.setObject(flowFast);
                            tj.setMsg("已转交，不能再进行办理！");
                            tj.setFlag(0);
                            return tj;
                        }
                    }
                }
            }
            String beginTime = DateFormat.getStrDate(new Date());
            //开始判断
            if (prcsId == 1 && ("").equals(id.trim())) {
                FlowRun flowRun = this.getRun(runName, flowId, users, beginTime, viewUser);
                int runId = flowRun.getRunId();
                flowRun.setUid(String.valueOf(users.getUid()));
                flowRun.setUserName(users.getUserName());
                flowRun.setEndTime("");
                //触发器设置
                // 域名获取，不包含端口号
//            String url =request.getScheme()+"://"+ request.getServerName()+"/";//+request.getRequestURI();
          /*      String url =request.getScheme()+"://"+ request.getServerName()+":"+
                        request.getServerPort()+"/workflow/work/workformPreView?flowId="+flowId+"&flowStep="+prcsId+"&runId="+runId+"&prcsId="+flowPrcs+"";//+request.getRequestURI();
                this.notifyNotice("0", users.getByname(), DateFormat.getDate(beginTime), flowName + " " +beginTime,
                        "<a href="+url+">"+url+"</a>", "", flowId, prcsId,this.returnMap().get(create),sqlType);*/

                flowRunPrcs = new FlowRunPrcs(runId, prcsId, users.getUserId(), beginTime, "2000-01-01 00:00:00", "2", 1, "1", "0", beginTime, "2000-01-01 00:00:00", users.getDeptId(), "0","0");
                workFlowServiceContext.getFlowRunPrcsService().save(flowRunPrcs);
                flowFast.setFlowRun(flowRun);
                flowFast.setFlowRunPrcs(flowRunPrcs);
                //是否允许会签
                String feedback = flowProcess.getFeedback();
                flowFast.setFeedback(feedback);
                //公共附件中的Office文档详细权限设置：(1-新建权限,2-编辑权限,3-删除权限,4-下载权限,5-打印权限,)
                flowFast.setAttachPriv(this.attachPriv(flowProcess));
            } else {
                FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(Integer.parseInt(id));

                if (StringUtils.checkNull(flowRun.getEndTime())) {
                    flowRun.setEndTime("");
                }
                Users users1 = usersService.getUsersByuserId(flowRun.getBeginUser());

                flowRun.setUid(String.valueOf(users1.getUid()));
                flowRun.setUserName(users1.getUserName());
                Map<String, Object> m = new HashMap<String, Object>();
                m.put("runId", id);
                m.put("prcsId", prcsId);
                m.put("prcsFlag", "2");
                m.put("prcsTime", DateFormat.getStrDate(new Date()));
                m.put("userId", users.getUserId());
                m.put("flowPrcs", flowPrcs);
                workFlowServiceContext.getFlowRunPrcsService().updateSql(m);
                m.put("prcsId", prcsId);
                List<FlowRunPrcs> listFloRunPrcs = workFlowServiceContext.getFlowRunPrcsService().findByRunId(m);
                flowRunPrcs = listFloRunPrcs.get(0);
                m.put("prcsFlag", "4");
                m.put("prcsId", prcsId - 1);
                m.put("userId", null);
                m.put("prcsTime", null);
                String parent = flowRunPrcs.getParent();
                //应对并发
                if (parent.split(",").length == 1) {
                    m.put("flowPrcs", flowRunPrcs.getParent());
                }
                workFlowServiceContext.getFlowRunPrcsService().updateSql(m);
                String feedback = flowProcess.getFeedback();
                flowFast.setFeedback(feedback);
                flowFast.setAttachPriv(this.attachPriv(flowProcess));
                flowFast.setFlowRun(flowRun);
                flowFast.setFlowRunPrcs(flowRunPrcs);
            }
            //强制合并
            //Integer gatherNodePriv = this.reGatherNodePriv(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId);
            Integer gatherNodePriv = this.findFlowPrcsProcess(String.valueOf(flowFast.getFlowRun().getRunId()), Integer.parseInt(flowPrcs), users.getUserId(), flowId, prcsId);

            flowFast.setGatherNodePriv(String.valueOf(gatherNodePriv));
            tj.setObject(flowFast);
            tj.setMsg("OK");
            tj.setFlag(0);

        } catch (Exception e) {
            tj.setMsg(e.getMessage());
            tj.setFlag(1);
        }
        return tj;
    }


    //用map存取所有流程步骤信息
    public Map<String, FlowProcess> allflowProcessBymap(List<FlowProcess> allFp) {
        Map<String, FlowProcess> map = new HashMap<String, FlowProcess>();
        //根据对应条件遍历流程步骤过滤
        for (int i = 0; i < allFp.size(); i++) {
            FlowProcess flowProcess = allFp.get(i);
            map.put(String.valueOf(flowProcess.getPrcsId()), flowProcess);
        }
        return map;
    }

    @Override
    public AjaxJson createGuide(String flowId, Users users, HttpServletRequest request) {
        AjaxJson ajaxJson = new AjaxJson();
        String sqlType = "xoa" + (String) request.getSession().getAttribute(
                "loginDateSouse");
        try {
            //获取所有的流程步骤
            List<FlowProcess> allFp = workFlowServiceContext.getFlowProcessService().findFlowId(Integer.parseInt(flowId));
            //表单类型
            //本部门
            Department dep = departmentService.getDeptById(users.getDeptId());
            FlowTypeModel flowTypeModel = (FlowTypeModel) workFlowServiceContext.getFlowTypeService().selectAllFlow(Integer.parseInt(flowId)).getObject();
            FlowFormType flowFormType = (FlowFormType) workFlowServiceContext.getFlowFormTypeService().qureyItemMax(flowTypeModel.getFormId()).getObject();
            String flowName = flowTypeModel.getFlowName();
            String autoName = flowTypeModel.getAutoName();
            String beginTime = DateFormat.getStrDate(new Date());
            String runName = this.lexicalParse(autoName, flowTypeModel, users, dep);

            Map<String, Object> attributes = new HashMap<String, Object>();
            attributes.put("AllFlowProcess", allFp);
            attributes.put("runName", runName);
            attributes.put("flowName", flowName);
            attributes.put("formId", flowFormType.getFormId());
            //流程说明文字
            attributes.put("flowDesc", flowTypeModel.getFlowDesc());
            attributes.put("flowType", flowTypeModel);
            attributes.put("attachmentId", flowTypeModel.getAttachmentId());
            attributes.put("attachmentName", flowTypeModel.getAttachmentName());
            attributes.put("attachList", GetAttachmentListUtil.returnAttachment(flowTypeModel.getAttachmentName(), flowTypeModel.getAttachmentId(), sqlType, GetAttachmentListUtil.MODULE_WORKFLOW));
            ajaxJson.setAttributes(attributes);
            ajaxJson.setFlag(true);
            ajaxJson.setMsg("OK");
            return ajaxJson;
        } catch (Exception e) {
            L.e("createGuide" + e.getMessage());
            ajaxJson.setMsg("fasle");
            ajaxJson.setFlag(false);
            return ajaxJson;
        }
    }


    public ToJson<FlowFast> exportFlowRun(HttpServletRequest request,
                                          Integer flowId,
                                          @RequestParam(value = "flowStep", required = false) Integer prcsId,
                                          @RequestParam(value = "prcsId", required = false) String flowProcs,
                                          @RequestParam(value = "runId", required = false) String runId,
                                          @RequestParam(value = "runName", required = false) String runName
    ) {
        FlowFast flowFast = new FlowFast();
        Map<String, Object> map = this.fastAdd(runId, String.valueOf(flowId));

        return null;
    }


    @Override
    public BaseWrapper getRunName(Users user, Integer flowId, Integer prcsId, String flowProcs) {
        BaseWrapper baseWrappers = new BaseWrapper();
        //本部门
        Department dep = departmentService.getDeptById(user.getDeptId());
        //获取工作流表单的样式
        //获取工作流表单的样式
        FlowFast flowFast = this.getWorkFromSetting(flowId);
        //获取条件判断
        flowFast = this.conditionSetting(flowFast, flowId, flowProcs);
        Map<String, FlowProcess> map = this.allflowProcessBymap(flowFast.getListFp());
        FlowProcess flowProcess = map.get(flowProcs);
        String flowName = flowFast.getFlowTypeModel().getFlowName();
        String autoName = flowFast.getFlowTypeModel().getAutoName();
        String beginTime = DateFormat.getStrDate(new Date());
        String runName = "";
        if (autoName != "") {
            runName = this.lexicalParse(autoName, flowFast.getFlowTypeModel(), user, dep);
        }
        baseWrappers.setStatus(true);
        baseWrappers.setFlag(true);
        baseWrappers.setData(runName);
        return baseWrappers;
    }

    //导出execl表格
    @Override
    public void exportExcel(Users users, String type, HttpServletResponse response) {
        List<FlowRunPrcs> resultList = new ArrayList<FlowRunPrcs>();
        if ("1".equals(type)) {
            resultList = this.getReceivedWorksList(users);
        } else if ("2".equals(type)) {
            resultList = this.getHandledWorksList(users);
        } else if ("3".equals(type)) {
            resultList = this.getAllWorksList(users);
        } else if ("4".equals(type)) {
            //resultList = getViewsWorksList(params, loginUser);
        } else if ("5".equals(type)) {
            //resultList = getSuspendedWorksList(params, loginUser);
        }

        // 获取当前时间
        Calendar c = Calendar.getInstance();
        String time = "" + c.get(Calendar.YEAR) + (c.get(Calendar.MONTH) + 1)
                + c.get(Calendar.DAY_OF_MONTH) + c.get(Calendar.HOUR_OF_DAY)
                + c.get(Calendar.MINUTE);

        try (OutputStream out = response.getOutputStream()) {
            HSSFWorkbook wb = new HSSFWorkbook();
            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = wb.createSheet("工作查询列表信息");
            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
            HSSFRow row = sheet.createRow((int) 0);
            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFFont font = wb.createFont();
            font.setFontHeightInPoints((short) 12); // 字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); // 字体颜色
            font.setFontName("宋体"); // 字体
            font.setBold(true); // 宽度
            font.setItalic(false); // 是否使用斜体
            HSSFCellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
            style.setFont(font);

            HSSFFont font1 = wb.createFont();
            font1.setFontHeightInPoints((short) 12); // 字体高度
            font1.setColor(HSSFFont.COLOR_NORMAL); // 字体颜色
            font1.setFontName("宋体"); // 字体
            font1.setBold(true); // 宽度
            font1.setItalic(false); // 是否使用斜体
            HSSFCellStyle style1 = wb.createCellStyle();
            style1.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
            style1.setFont(font1);

            HSSFCell cell = row.createCell((short) 0);
            List<String> head = new ArrayList<String>();

            StringBuffer stringBuffer = new StringBuffer();

            String[] d = {"流水号", "流程名称", "我经办的步骤", "发起人", "状态", "到达时间", "已停留"};
            ;//待办
            String[] b = {"流水号", "流程名称", "工作名称/文号", "发起人", "办结时间", "流程状态"};//办结
            String[] q = {"流水号", "流程名称", "工作名称/文号", "发起人", "办结时间", "流程状态"};//全部
            if ("1".equals(type)) {
                for (int i = 0; i < d.length; i++) {
                    cell.setCellValue(d[i]);
                    cell.setCellStyle(style);
                    cell = row.createCell((short) (i + 1));
                }
                // 设置内容
                Map map = new HashMap();
                for (int m = 0; m < resultList.size(); m++) {
                    HSSFRow r = sheet.createRow((int) (m + 1));
                    //map = (Map) resultList.get(m);
                    FlowRunPrcs flowRunPrcs = resultList.get(m);
                    map.put(0, flowRunPrcs.getRunId());
                    map.put(1, flowRunPrcs.getFlowRun().getRunName());
                    map.put(2, "第" + flowRunPrcs.getFlowProcess().getPrcsId() + "步:" + flowRunPrcs.getFlowProcess().getPrcsName());
                    map.put(3, flowRunPrcs.getUserName());
                    map.put(4, this.returnFlag(flowRunPrcs.getPrcsFlag()));
                    map.put(5, flowRunPrcs.getReceiptTime());
                    map.put(6, flowRunPrcs.getArriveTime());
                    for (int n = 0; n < map.size(); n++) {
                        cell = r.createCell((short) (n));
                        cell.setCellValue(String.valueOf(map.get(n)));
                        cell.setCellStyle(style1);
                    }
                }
                stringBuffer.append("待办工作列表").append(time.toString()).append(".xls");
            }
            if ("2".equals(type)) {
                for (int i = 0; i < b.length; i++) {
                    cell.setCellValue(b[i]);
                    cell.setCellStyle(style);
                    cell = row.createCell((short) (i + 1));
                }

                // 设置内容
                Map map = new HashMap();
                for (int m = 0; m < resultList.size(); m++) {
                    HSSFRow r = sheet.createRow((int) (m + 1));
                    //map = (Map) resultList.get(m);
                    FlowRunPrcs flowRunPrcs = resultList.get(m);
                    map.put(0, flowRunPrcs.getRunId());
                    map.put(1, flowRunPrcs.getFlowRun().getRunName());
                    map.put(2, "第" + flowRunPrcs.getFlowProcess().getPrcsId() + "步:" + flowRunPrcs.getFlowProcess().getPrcsName());
                    map.put(3, flowRunPrcs.getUserName());
                    map.put(4, flowRunPrcs.getDeliverTime());
                    map.put(5, this.returnFlag(flowRunPrcs.getPrcsFlag()));
                    for (int n = 0; n < map.size(); n++) {
                        cell = r.createCell((short) (n));
                        cell.setCellValue(String.valueOf(map.get(n)));
                        cell.setCellStyle(style1);
                    }
                }
                stringBuffer.append("办结工作列表").append(time.toString()).append(".xls");
            }
            if ("3".equals(type)) {
                for (int i = 0; i < b.length; i++) {
                    cell.setCellValue(b[i]);
                    cell.setCellStyle(style);
                    cell = row.createCell((short) (i + 1));
                }

                // 设置内容
                Map map = new HashMap();
                for (int m = 0; m < resultList.size(); m++) {
                    HSSFRow r = sheet.createRow((int) (m + 1));
                    //map = (Map) resultList.get(m);
                    FlowRunPrcs flowRunPrcs = resultList.get(m);
                    map.put(0, flowRunPrcs.getRunId());
                    map.put(1, flowRunPrcs.getFlowType().getFlowName());
                    map.put(2, flowRunPrcs.getFlowRun().getRunName());
                    map.put(3, flowRunPrcs.getUserName());
                    map.put(4, "第" + flowRunPrcs.getFlowProcess().getPrcsId() + "步:" + flowRunPrcs.getFlowProcess().getPrcsName());
                    map.put(5, this.returnFlag(flowRunPrcs.getPrcsFlag()));
                    for (int n = 0; n < map.size(); n++) {
                        cell = r.createCell((short) (n));
                        cell.setCellValue(String.valueOf(map.get(n)));
                        cell.setCellStyle(style1);
                    }
                }
                stringBuffer.append("全部工作列表").append(time.toString()).append(".xls");
            }

            // 设置每一列的宽度
            sheet.setDefaultColumnWidth(15);
            String fileName = stringBuffer.toString();
            response.setHeader("Content-disposition", "attachment;filename="
                    + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");
            wb.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //查询我的待办流程列表
    public List<FlowRunPrcs> getHandledWorksList(Users users) {
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("userId", users.getUserId());
        ToJson<FlowRunPrcs> toJson = workFlowServiceContext.getFlowRunPrcsService().selectEnd(maps, null, null, false);
        List<FlowRunPrcs> list = toJson.getObj();
        return list;
    }


    //查询办结流程
    public List<FlowRunPrcs> getReceivedWorksList(Users users) {
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("userId", users.getUserId());
        ToJson<FlowRunPrcs> toJson = workFlowServiceContext.getFlowRunPrcsService().selectObject(maps, null, null, false);
        List<FlowRunPrcs> list = toJson.getObj();
        return list;
    }

    //查询全部工作
    public List<FlowRunPrcs> getAllWorksList(Users users) {
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("userId", users.getUserId());
        ToJson<FlowRunPrcs> toJson = workFlowServiceContext.getFlowRunPrcsService().selectAll(maps, null, null, false);
        List<FlowRunPrcs> list = toJson.getObj();
        return list;
    }

    public static String returnFlag(String prcsFlag) {
        if (prcsFlag.equals("1")) {
            return "未接收";
        }
        if (prcsFlag.equals("2")) {
            return "办理中";
        }
        if (prcsFlag.equals("3")) {
            return "转交下一步，下一步经办人无人接收";
        }
        if (prcsFlag.equals("4")) {
            return "已办结";
        }
        if (prcsFlag.equals("5")) {
            return "自由流程预设步骤";
        }
        if (prcsFlag.equals("6")) {
            return "已挂起";
        }
        return "";
    }


    //文号生成规则
    public String lexicalParse(String str, FlowTypeModel flowTypeModel, Users users, Department department) {
        Calendar now = Calendar.getInstance();
        int autoNum = flowTypeModel.getAutoNum();
        int autoLength = flowTypeModel.getAutoLen();
        ++autoNum;
        flowTypeModel.setAutoNum(autoNum);
        workFlowServiceContext.getFlowTypeModelMapper().update(flowTypeModel);
        str = str.replace(DocumentConstants.year, now.get(Calendar.YEAR) + "");
        str = str.replace(DocumentConstants.month, now.get(Calendar.MONTH) + 1 + "");
        str = str.replace(DocumentConstants.day, now.get(Calendar.DAY_OF_MONTH) + "");
        str = str.replace(DocumentConstants.hour, now.get(Calendar.HOUR_OF_DAY) + "");
        str = str.replace(DocumentConstants.minute, now.get(Calendar.MINUTE) + "");
        str = str.replace(DocumentConstants.second, now.get(Calendar.SECOND) + "");
        str = str.replace(DocumentConstants.flow, flowTypeModel.getFlowName());
        str = str.replace(DocumentConstants.user, users.getUserName());
        str = str.replace(DocumentConstants.role, users.getUserPrivName());
        str = str.replace(DocumentConstants.flowName, users.getUserName());
        str = str.replace(DocumentConstants.shortDept, department.getDeptName());
        str = str.replace(DocumentConstants.longDept, departmentService.longDepName(department.getDeptId()));
        str = str.replace(DocumentConstants.number, org.apache.commons.lang3.StringUtils.repeat("0", autoLength - String.valueOf(autoNum).length()) + autoNum);
        //str = str.replace(DocumentConstants.runId, id);
        return str;
    }

    private FlowRun getRun(String runName, int flowId, Users users, String beginTime, String viewUser) throws InterruptedException {
        FlowRun flowRun = new FlowRun();
        synchronized (this) {
            int runId = workFlowServiceContext.getFlowRunService().getMaxRunId() + 1;
            flowRun = new FlowRun(runId, runName, flowId, users.getUserId(), beginTime, users.getDeptId(), "0");
            flowRun.setViewUser(viewUser);
            workFlowServiceContext.getFlowRunService().save(flowRun);
            flowRun.setUserName(users.getUserName());
        }
        return flowRun;
    }

    /**
     * 创建作者:   季佳伟
     * 创建日期:   2017/8/23 16:20
     * 方法介绍:   根据前台传入的runId,prcsId,toId,flowPrcs,opFlag,从session中获取users
     * 先根据runId，prcsId获取FlowRunPrcs修改其状态flowPrcs=4，opFlag= 0
     * 再添加FlowRunPrcs设置其runId,prcsId,userId=toId,flowPrcs= 1
     * opFlag= 1 ,otherUser=userId
     * 参数说明:
     *
     * @return
     */
    @Override
    public ToJson<FlowRunPrcs> entrust(String runId, String prcsId, String toId,
                                       String flowPrcs, String opFlag, Users users) {
        ToJson<FlowRunPrcs> json = new ToJson<FlowRunPrcs>();
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("runId", runId);
            map.put("prcsId", prcsId);
            map.put("prcsFlag", 4);
            map.put("opFlag", 0);
            workFlowServiceContext.getFlowRunPrcsService().updateSql(map);
            FlowRunPrcs flowRunPrcs = new FlowRunPrcs();
            flowRunPrcs.setRunId(Integer.parseInt(runId));
            flowRunPrcs.setPrcsId(Integer.parseInt(prcsId));
            flowRunPrcs.setFlowPrcs(Integer.parseInt(flowPrcs));
            flowRunPrcs.setUserId(toId);
            flowRunPrcs.setPrcsFlag("1");
            flowRunPrcs.setOpFlag("1");
            flowRunPrcs.setOtherUser(users.getUserId() + ",");
            workFlowServiceContext.getFlowRunPrcsService().save(flowRunPrcs);
            json.setMsg("true");
            json.setFlag(0);
        } catch (Exception e) {
            e.printStackTrace();
            json.setFlag(1);
            json.setMsg("error");
        }
        return json;
    }

    //判断是否有传阅权限
    public String checkViewPriv(int ftViewPriv, int fpViewPriv) {
        if (ftViewPriv == 1) {
            if (fpViewPriv == 1) {
                return "1";
            }
        }
        return "0";
    }

    //强制合并判断
    public Integer reGatherNodePriv(String runId, Integer flowPrcs, String userId, Integer flowId) {
        Map<Integer, FlowProcess> m1 = new HashMap<Integer, FlowProcess>();
        StringBuffer stringBuffer = new StringBuffer();
        List<Integer> listPrcs = new ArrayList<Integer>();
        List<Integer> listFlag = new ArrayList<Integer>();
        //返回所有可以到达此节点的flowProcess
        Map<Integer, FlowProcess> map = this.reAll(m1, flowId, flowPrcs);
        if (map.size() == 0) {
            return 0;
        }

        //通过entrySet()方法将map集合中的映射关系取出（这个关系就是Map.Entry类型）
        Set<Map.Entry<Integer, FlowProcess>> entrySet = map.entrySet();

        //将关系集合entrySet进行迭代，存放到迭代器中
        Iterator<Map.Entry<Integer, FlowProcess>> it2 = entrySet.iterator();

        while (it2.hasNext()) {
            Map.Entry<Integer, FlowProcess> me = it2.next();//获取Map.Entry关系对象me
            Integer key2 = me.getKey();//通过关系对象获取key
            listPrcs.add(key2);
        }
        listFlag.add(1);
        listFlag.add(2);

        Map<String, Object> m = new HashMap<String, Object>();
        m.put("runId", runId);
        m.put("flowPrcs", flowPrcs);
        m.put("listPrcs", listPrcs);
        m.put("listFlag", listFlag);
        m.put("userId", userId);
        Integer gatherNodePriv = workFlowServiceContext.getFlowRunPrcsService().checkGatherNode(m);
        if (gatherNodePriv == null) {
            return 0;
        } else {
            return 1;
        }

    }

    //遍历获取所有符合的flowProcess
    public Map<Integer, FlowProcess> reAll(Map<Integer, FlowProcess> map, Integer flowId, Integer flowPrcs) {
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("flowId", flowId);
        map1.put("flowPrcs", flowPrcs);
        List<FlowProcess> list = workFlowServiceContext.getFlowProcessMapper().findProcseePrcsTo(map1);
        for (FlowProcess flowProcess : list) {
            map.put(flowProcess.getPrcsId(), flowProcess);
            reAll(map, flowId, flowProcess.getPrcsId());
        }
        return map;
    }


    //工作关注
    @Override
    public AjaxJson workAttention(Integer runId, String userId, String status) {
        AjaxJson ajaxJson = new AjaxJson();
        FlowRun flowRun = workFlowServiceContext.getFlowRunService().find(runId);
        String focusUser = flowRun.getFocusUser();
        if (status.equals("0")) {
            focusUser = focusUser.replaceAll(userId, "");
        } else {
            focusUser = focusUser + userId;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", runId);
        map.put("userId", focusUser);
        map.put("status", status);
        try {
            int a = workFlowServiceContext.getFlowRunService().updateFocusUser(map);
            if (a > 0) {
                ajaxJson.setFlag(true);
                ajaxJson.setMsg("OK");
            } else {
                ajaxJson.setFlag(false);
                ajaxJson.setMsg("false");
            }
        } catch (Exception e) {
            ajaxJson.setFlag(false);
            ajaxJson.setMsg(e.getMessage());
        }
        return ajaxJson;
    }

    //工作结束和工作删除,状态值0为工作结束1为工作删除
    @Override
    public AjaxJson worDelete(Integer runId, String status) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, Object> map = new HashMap<String, Object>();

        try {
            if (status.equals("0")) {
                String endTime = DateFormat.getStrDate(new Date());//设置日期格式
                map.put("runId", runId);
                map.put("endTime", endTime);
                workFlowServiceContext.getFlowRunService().updateEnd(map);
            } else {
                map.put("runId", runId);
                map.put("delFlag", 1);
                workFlowServiceContext.getFlowRunService().updateEnd(map);
            }
            ajaxJson.setMsg("OK");
            ajaxJson.setFlag(true);
        } catch (Exception e) {
            e.printStackTrace();
            ajaxJson.setMsg(e.getMessage());
            ajaxJson.setFlag(false);
        }
        return ajaxJson;
    }

    @Override
    @Async
    public void todoWorkSmsBoby(final String beginUser, final String flowPrcs, final String tableName, final String runId, final String runName, final String flowId, final String prcsId, final String currentPrcsId, final String tabId, final String topDefault, final String smsContent, final HttpServletRequest request, final String smsType, final Users users, final String orgadd, final String jingbanUser, final String viewUser) {
        final String sqlType = (String) request.getSession().getAttribute("loginDateSouse");
        this.threadPoolTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                ContextHolder.setConsumerType("xoa" + sqlType);
                ToJson json = new ToJson();
                //短信发送(判断三段是否有权限发送短信)
                //json = sms2PrivService.selectSms2("1", request);
                //短信发送权限判断模块未写完，暂默认发送
                json.setCode("1");
                //String topDefault = request.getParameter("topDefault");
                //主办人相关选项数组
                String[] topArray = null;
                if (StringUtils.checkNull(topDefault)) {
                    topArray = new String[1];
                    topArray[0] = "0";
                } else {
                    topArray = topDefault.split(",");
                }
                //并发步骤数组
                String[] condition = flowPrcs.split(",");
                //经办人数组
                String[] jingbanStr = jingbanUser.split("\\|");//遍历经办人
                //主办人数组
                String[] beginStr=null;
                if (!StringUtils.checkNull(beginUser)){
                    beginStr = beginUser.split(",");
                }
                //流程发起人 此处可做优化判断事务提醒按钮是否勾选3，4
                FlowRun flowRun = flowRunMapper.find(Integer.parseInt(runId));
                //全部经办人  此处可做优化判断事务提醒按钮是否勾选5，6
                String allUserId = flowRunPrcsMapper.getAllUserName(runId, users.getUserId());
                if (!StringUtils.checkNull(smsType)) {//获取界面勾选的事物提醒的按钮
                    String[] strOrgAdd = smsType.split(",");//如果用户勾选，将数组遍历
                    for (int j = 0; j < strOrgAdd.length; j++) {
                        if (!StringUtils.checkNull(strOrgAdd[j])) {
                            switch (Integer.parseInt(strOrgAdd[j])) {
                                case 1: //如果等于1 则提醒下一步骤人员
                                    //判断是否是并发
                                    for (int i = 0; i < condition.length; i++) {
                                        //主办人相关选项
                                        switch (topArray[i]) {
                                            case "0":
                                                if (!StringUtils.checkNull(beginUser)){
                                                    handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);

                                                }
                                                break;
                                            case "1":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 1, smsContent);
                                                break;
                                            case "2":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                                break;
                                            case "3":
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                    break;
                                case 2: //如果等于2 则短信提醒下一步骤人员
                                    for (int i = 0; i < condition.length; i++) {
                                        SMSreminder(jingbanStr[i], runId, runName, json, smsContent);
                                    }
                                    break;
                                case 3://3 发起人提醒
                                    if (flowRun != null) {
                                        seeReminder(flowRun.getBeginUser(), runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 4://4 发起人短信提醒
                                    if (flowRun != null) {
                                        SMSreminder(flowRun.getBeginUser(), runId, runName, json, smsContent);
                                    }
                                    break;
                                case 5://5 全部经办人提醒
                                    //获取全部经办人（已去除重复数据和当前用户）
                                    if (!StringUtils.checkNull(allUserId)) {
                                        seeReminder(allUserId, runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 6://6 全部经办人短信提醒
                                    if (!StringUtils.checkNull(allUserId)) {
                                        SMSreminder(allUserId, runId, runName, json, smsContent);
                                    }
                                    break;
                                case 7://7 催办提醒
                                    for (int i = 0; i < condition.length; i++) {
                                        handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                    }
                                    break;
                                case 8://8 传阅人事务提醒
                                    // 如果用户勾选，将数组遍历
                                    if (!StringUtils.checkNull(viewUser)) {
                                        seeReminder(viewUser, runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 9://8 传阅人短信提醒
                                    if (!StringUtils.checkNull(viewUser)) {
                                        SMSreminder(viewUser, runId, runName, json, smsContent);
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
        });
    }

    @Async
    public void todoWorkSmsBoby2(final String flowPrcs, final String tableName, final String runId, final String runName, final String flowId, final String prcsId, final String currentPrcsId, final String tabId, final String smsContent, final HttpServletRequest request, final String smsType, final Users users, final String orgadd, final String jingbanUser, final String viewUser) {
        final String sqlType = (String) request.getSession().getAttribute("loginDateSouse");
        this.threadPoolTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                ContextHolder.setConsumerType("xoa" + sqlType);
                ToJson json = new ToJson();
                //短信发送(判断三段是否有权限发送短信)
                //json = sms2PrivService.selectSms2("1", request);
                //短信发送权限判断模块未写完，暂默认发送
                json.setCode("1");
                //String topDefault = request.getParameter("topDefault");
                //主办人相关选项数组
           /*     String[] topArray = null;
                if (StringUtils.checkNull(topDefault)) {
                    topArray = new String[1];
                    topArray[0] = "0";
                } else {
                    topArray = topDefault.split(",");
                }*/
                //并发步骤数组
                String[] condition = flowPrcs.split(",");
                //经办人数组
                String[] jingbanStr = jingbanUser.split("\\|");//遍历经办人
                //主办人数组
            /*    String[] beginStr=null;
                if (!StringUtils.checkNull(beginUser)){
                    beginStr = beginUser.split(",");
                }*/
                //流程发起人 此处可做优化判断事务提醒按钮是否勾选3，4
                FlowRun flowRun = flowRunMapper.find(Integer.parseInt(runId));
                //全部经办人  此处可做优化判断事务提醒按钮是否勾选5，6
                String allUserId = flowRunPrcsMapper.getAllUserName(runId, users.getUserId());
                if (!StringUtils.checkNull(smsType)) {//获取界面勾选的事物提醒的按钮
                    String[] strOrgAdd = smsType.split(",");//如果用户勾选，将数组遍历
                    for (int j = 0; j < strOrgAdd.length; j++) {
                        if (!StringUtils.checkNull(strOrgAdd[j])) {
                            switch (Integer.parseInt(strOrgAdd[j])) {
                                case 1: //如果等于1 则提醒下一步骤人员
                                    //判断是否是并发
                               /*     for (int i = 0; i < condition.length; i++) {
                                        //主办人相关选项
                                        switch (topArray[i]) {
                                          *//*  case "0":
                                                if (!StringUtils.checkNull(beginUser)){
                                                    handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);

                                                }
                                                break;*//*
                                            case "1":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 1, smsContent);
                                                break;
                                            case "2":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                                break;
                                            case "3":
                                                break;
                                            default:
                                                break;
                                        }
                                    }*/
                                    break;
                                case 2: //如果等于2 则短信提醒下一步骤人员
                                    for (int i = 0; i < condition.length; i++) {
                                        SMSreminder(jingbanStr[i], runId, runName, json, smsContent);
                                    }
                                    break;
                                case 3://3 发起人提醒
                                   /* if (flowRun != null) {
                                        seeReminder(flowRun.getBeginUser(), runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }*/
                                    break;
                                case 4://4 发起人短信提醒
                                /*    if (flowRun != null) {
                                        SMSreminder(flowRun.getBeginUser(), runId, runName, json, smsContent);
                                    }
                                    break;*/
                                case 5://5 全部经办人提醒
                                    //获取全部经办人（已去除重复数据和当前用户）
                                    if (!StringUtils.checkNull(jingbanStr[j])) {
                                        handleReminder(null,jingbanStr[j], runId, flowId, (Integer.parseInt(prcsId)-1)+"", currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, 0,smsContent);
                                    }
                                    break;
                                case 6://6 全部经办人短信提醒
                                    if (!StringUtils.checkNull(jingbanStr[j])) {
                                        SMSreminder(jingbanStr[j], runId, runName, json, smsContent);
                                    }
                                    break;
                                case 7://7 催办提醒
                                  /*  for (int i = 0; i < condition.length; i++) {
                                        handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                    }*/
                                    break;
                                case 8://8 传阅人事务提醒
                                    // 如果用户勾选，将数组遍历
                           /*         if (!StringUtils.checkNull(viewUser)) {
                                        seeReminder(viewUser, runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }*/
                                    break;
                                case 9://8 传阅人短信提醒
                             /*       if (!StringUtils.checkNull(viewUser)) {
                                        SMSreminder(viewUser, runId, runName, json, smsContent);
                                    }*/
                                    break;
                            }
                        }
                    }
                }
            }
        });
    }



    @Override
    public AjaxJson saveHandle(Integer runId, String prcsId, String flowPrcs, Users users) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, Object> maps = new HashMap<String, Object>();
        try {
            maps.put("prcsId", prcsId);
            maps.put("runId", runId);
            maps.put("prcsFlag", "4");
            maps.put("deliverTime", DateFormat.getStrDate(new Date()));
            maps.put("userId", users.getUserId());
            //应对并发
            maps.put("flowPrcs", flowPrcs);
            workFlowServiceContext.getFlowRunPrcsService().updateSql(maps);
            ajaxJson.setFlag(true);
            ajaxJson.setMsg("OK");
        } catch (Exception e) {
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("false");
        }
        return ajaxJson;
    }

    /* */

    /**
     * lr
     * 插入一条日志
     *
     * @param runId
     * @return
     *//*
    @Override
    public int setFlowRunLog(Integer runId,Integer flowPrcs,String type,String content) {
        int count=0;
        FlowRunLog flowRunLog=flowRunLogMapper.selectFlowRunLogByRunId(runId,flowPrcs);
        if(flowRunLog!=null){
           *//* String ip=IpAddr.getIpAddr(request);
            flowRunLog.setIp(ip);*//*
            flowRunLog.setTime(new Date());
            flowRunLog.setContent(content);
            flowRunLog.setType(type);

            count=flowRunLogMapper.insert(flowRunLog);
        }
        return count;
    }*/
//并发强制合并修改-wym
    public Integer findFlowPrcsProcess(String runId, Integer flowPrcs, String userId, Integer flowId, Integer prcsId) {
        //找到当前flow_run_prcs
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("prcsId", prcsId - 1);
        map.put("runId", runId);
        //查询上一步流程合并
        List<FlowRunPrcs> list = wfeFlowRunPrcs.selectFind(map);
        map.put("flowPrcs", flowPrcs);
        map.put("userId", userId);

        for (FlowRunPrcs flowRunPrcs : list) {
            if ("".equals(flowRunPrcs.getBranchCount()) || flowRunPrcs.getBranchCount() == null) {
                return 0;
            }
            String process = flowRunPrcs.getBranchCount();
            String[] processStr = process.split(",");
            List<Integer> listPrcs = new ArrayList<Integer>();
            List<Integer> listFlag = new ArrayList<Integer>();
            listFlag.add(1);
            listFlag.add(2);
            //判断是否已办结
            for (int i = 0; i < processStr.length; i++) {
                listPrcs.add(Integer.parseInt(processStr[i]));
            }
            Map<String, Object> m = new HashMap<String, Object>();
            m.put("runId", runId);
            m.put("flowPrcs", "");
            m.put("listFlag", listFlag);
            m.put("listPrcs", listPrcs);
            Integer gatherNodePriv = workFlowServiceContext.getFlowRunPrcsService().checkGatherNode(m);
            if (gatherNodePriv == null) {
                return 0;
            }
            return 1;
        }
        return 1;
    }

    /**
     * 工作流事务提醒办理公用方法 适用单步骤
     *
     * @param handleUser 步骤办理人员
     * @param runId      流水号
     * @param flowId     流程id
     * @param prcsId     流程实例步骤号
     * @param flowPrcs   流程步骤号
     * @param runName    流程名
     * @param tableName  公文表名
     * @param tabId      公文id
     * @param userId     用户id
     * @param sqlType    数据库库名
     * @param opflag     是否主办(0-经办,1-主办)
     * @author zlf
     */
    public void seeReminder(String handleUser, String runId, String flowId, String prcsId, String currentPrcsId, String runName, String tableName, String tabId, String userId, String sqlType, String smsContent) {
        SmsBody smsBody = new SmsBody();
        String title = "";
        String context = "";
        String remindUrl = "/workflow/work/workformPreView?flowId=" + flowId + "&flowStep=" + prcsId + "&runId=" + runId + "&prcsId=" + currentPrcsId;
        //  String smsContent = "流水号：" + runId + "，工作名称/文号：" + runName;
        boolean bol = false;
                    SysPara myproject = sysParaMapper.querySysPara("MYPROJECT");
                    if(myproject != null && !StringUtils.checkNull(myproject.getParaValue())
                            && "dazu".equals(myproject.getParaValue())){
                        bol=true;
                    }

        if ("document".equals(tableName)) {//如果是公文
            title = bol ? runName : "您有新的公文需要签阅";
            context = "流水号：" + runId + "，公文文号：" + runName;
            remindUrl = "/workflow/work/workformPreView?flowId=" + flowId + "&flowStep=" + prcsId + "&tableName=" + tableName + "&tabId=" + tabId + "&runId=" + runId + "&prcsId=" + currentPrcsId + "&isNomalType=false&hidden=true";
            smsBody = new SmsBody(userId, "70", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        } else if ("budget".equals(tableName)) {
            title = bol ? runName :  "您有新的工作需要办理";
            remindUrl += "&tableName=budget";
            context = "流水号：" + runId + "，工作名称/文号：" + runName;
            smsBody = new SmsBody(userId, "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        } else {//否则是工作流
            title = bol ? runName :  "您有新的工作需要办理";
            context = "流水号：" + runId + "，工作名称/文号：" + runName;
            smsBody = new SmsBody(userId, "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        }
        String[] toIds = handleUser.split(",");
        for (int i = 0; i < toIds.length; i++) {
            smsBody.setToId(toIds[i]);
            smsBody.setBodyId(null);
            smsService.saveSms(smsBody, toIds[i], "1", "1", title, context, sqlType);//存储事物提醒并推送消息

        }
    }


    /**
     * 工作流事务提醒办理公用方法 适用单步骤
     *
     * @param handleUser 步骤办理人员
     * @param runId      流水号
     * @param flowId     流程id
     * @param prcsId     流程实例步骤号
     * @param flowPrcs   流程步骤号
     * @param runName    流程名
     * @param tableName  公文表名
     * @param tabId      公文id
     * @param userId     用户id
     * @param sqlType    数据库库名
     * @param opflag     是否主办(0-经办,1-主办)
     */
    public void handleReminder(String beginUser, String handleUser, String runId, String flowId, String prcsId, String flowPrcs, String runName, String tableName, String tabId, String userId, String sqlType, Integer opflag, String smsContent) {
        try {
            //lr 暂时子流程不发事物提醒
            //查看是否为子流程
            FlowProcess flowProcess = wfeFlowProcessMapper.findProcess(Integer.valueOf(flowId), Integer.valueOf(flowPrcs));
            if (flowProcess != null && flowProcess.getPrcsType() == 1) {
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean bol = false;
        SysPara myproject = sysParaMapper.querySysPara("MYPROJECT");
        if (myproject != null && !StringUtils.checkNull(myproject.getParaValue())
                && "dazu".equals(myproject.getParaValue())) {
            bol = true;
        }
        SmsBody smsBody = new SmsBody();
        String remindUrl = "/workflow/work/workform?opflag=" + opflag + "&flowId=" + flowId + "&flowStep=" + (Integer.parseInt(prcsId) + 1) + "&runId=" + runId + "&prcsId=" + flowPrcs;
        //String smsContent = "流水号：" + runId + "，工作名称/文号：" + runName;
        String title = "";
        String context = "";
        if ("document".equals(tableName)) {//如果是公文
            title = bol ? runName : "您有新的公文需要签阅";
            context = "流水号：" + runId + "，公文文号：" + runName;
            remindUrl = "/workflow/work/workform?opflag=" + opflag + "&flowId=" + flowId + "&flowStep=" + (Integer.parseInt(prcsId) + 1) + "&tableName=" + tableName + "&tabId=" + tabId + "&runId=" + runId + "&prcsId=" + flowPrcs + "&isNomalType=false";
            smsBody = new SmsBody(userId, "70", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        } else if ("budget".equals(tableName)) {
            title = bol ? runName : "您有新的工作需要办理";
            context = "流水号：" + runId + "，工作名称/文号：" + runName;
            remindUrl += "&tableName=budget";
            smsBody = new SmsBody(userId, "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        } else {//否则是工作流
            title = bol ? runName : "您有新的工作需要办理";
            context = "流水号：" + runId + "，工作名称/文号：" + runName;
            smsBody = new SmsBody(userId, "7", DateFormat.getTime(DateFormat.getCurrentTime()), remindUrl, smsContent);
        }
        String[] toIds = handleUser.split(",");
        for (int i = 0; i < toIds.length; i++) {
            smsBody.setToId(toIds[i]);
            //判断是否发送给主办人
            if (!StringUtils.checkNull(beginUser) && toIds[i].equals(beginUser)) {
                String remindUrl1 = remindUrl.replace("opflag=0", "opflag=1");
                //被委托人
                String toId = getUserId(runId, toIds[i]);
                smsBody.setToId(toId);
                smsBody.setRemindUrl(remindUrl1);
            } else {
                smsBody.setRemindUrl(remindUrl);
            }
            smsBody.setBodyId(null);
            smsService.saveSms(smsBody, toIds[i], "1", "1", title, context, sqlType);//存储事物提醒并推送消息
        }
        // 企业微信提醒,因为企业微信不支持安卓和ios方法本身就是浏览器所以传递一个状态标识
        String replaceurl = smsBody.getRemindUrl().replace("workform", "workformh5")+"&type=EWC";
        qywxService.sendMsg(Arrays.asList(toIds),title,context,replaceurl,false);
    }

    /**
     * 短信提醒公共类
     *
     * @param handleUser 提醒人员
     * @param runId      流水号
     * @param runName    流程名称
     * @param json       是否有发送信息权限
     */
    public void SMSreminder(String handleUser, String runId, String runName, ToJson json, String smsContent) {
        //  StringBuffer contextString = new StringBuffer("您有流水号：" + runId + " 工作名称/文号：" + runName + " 的工作流或公文待查阅或办理");
        StringBuffer contextString = new StringBuffer(smsContent);
        String uId = "";
        if (json != null) {
            if (json.getCode().equals("1")) {
                if (!StringUtils.checkNull(handleUser)) {
                    String[] userIdArray = handleUser.split(",");
                    List<Users> list = usersMapper.getUsersByUserIds(userIdArray);
                    for (int i = 0; i < list.size(); i++) {
                        uId += list.get(i).getUid() + ",";
                    }
                }
                if (!StringUtils.checkNull(uId)){
                    sms2PrivService.smsSenders(contextString, uId);
                }

                // sms2PrivServiceImpl.selSenderMobile("0",sms2Priv,contextString,request);
            }
        }

    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：根据传入的runId和userId来检测此用户和流程是否有委托规则，如果有，返回被委托人userId
     * @创建时间：10:23 2018/7/24
     **/
    private String getUserId(String runId, String userId) {
        //根据flowId和userId查出FlowRule对象
        List<FlowRule> flowRuleList = flowRuleMapper.getFlowRuleList(runId, userId);
        if (flowRuleList.size() != 0) {
            //为了兼容老版本，可能有相同的委托规则
            FlowRule flowRule = flowRuleList.get(0);
            //查询出来的对象不能为空
            if (flowRule != null) {
                //判断状态是不是“1”开启状态
                if (flowRule.getStatus().equals("1")) {
                    //判断是不是一直有效（也就是时间为null）
                    if (flowRule.getBeginDate() == null && flowRule.getEndDate() == null) {
                        return flowRule.getToId();
                    } else {
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            //当前系统时间
                            Date atDate = new Date();
                            //开始时间
                            Date beginDate = sdf.parse(flowRule.getBeginDate());

                            //结束时间
                            Date endDate = sdf.parse(flowRule.getEndDate());

                            if (atDate.before(endDate) && atDate.after(beginDate)) {
                                return flowRule.getToId();
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }
    /**
     *
     * @方法描述：重写的todoWorkSmsBoby方法。定时任务自动保存转交的方法，方法不能出现request,需要的值必须得传
     *
     **/
    @Override
    @Async
    public void todoWorkSmsBobys(final String beginUser, final String flowPrcs, final String tableName, final String runId, final String runName, final String flowId, final String prcsId, final String currentPrcsId, final String tabId, final String topDefault, final String smsContent, final String smsType, final Users users, final String orgadd, final String jingbanUser, final String viewUser) {
        final String sqlType = "1001";
        this.threadPoolTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                ContextHolder.setConsumerType("xoa" + sqlType);
                ToJson json = new ToJson();
                //短信发送(判断三段是否有权限发送短信)
                //json = sms2PrivService.selectSms2("1", request);
                //短信发送权限判断模块未写完，暂默认发送
                json.setCode("1");
                //String topDefault = request.getParameter("topDefault");
                //主办人相关选项数组
                String[] topArray = null;
                if (StringUtils.checkNull(topDefault)) {
                    topArray = new String[1];
                    topArray[0] = "0";
                } else {
                    topArray = topDefault.split(",");
                }
                //并发步骤数组
                String[] condition = flowPrcs.split(",");
                //经办人数组
                String[] jingbanStr = jingbanUser.split("\\|");//遍历经办人
                //主办人数组
                String[] beginStr=null;
                if (!StringUtils.checkNull(beginUser)){
                    beginStr = beginUser.split(",");
                }
                //流程发起人 此处可做优化判断事务提醒按钮是否勾选3，4
                FlowRun flowRun = flowRunMapper.find(Integer.parseInt(runId));
                //全部经办人  此处可做优化判断事务提醒按钮是否勾选5，6
                String allUserId = flowRunPrcsMapper.getAllUserName(runId, users.getUserId());
                if (!StringUtils.checkNull(smsType)) {//获取界面勾选的事物提醒的按钮
                    String[] strOrgAdd = smsType.split(",");//如果用户勾选，将数组遍历
                    for (int j = 0; j < strOrgAdd.length; j++) {
                        if (!StringUtils.checkNull(strOrgAdd[j])) {
                            switch (Integer.parseInt(strOrgAdd[j])) {
                                case 1: //如果等于1 则提醒下一步骤人员
                                    //判断是否是并发
                                    for (int i = 0; i < condition.length; i++) {
                                        //主办人相关选项
                                        switch (topArray[i]) {
                                            case "0":
                                                if (!StringUtils.checkNull(beginUser)){
                                                    handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);

                                                }
                                                break;
                                            case "1":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 1, smsContent);
                                                break;
                                            case "2":
                                                handleReminder("", jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                                break;
                                            case "3":
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                    break;
                                case 2: //如果等于2 则短信提醒下一步骤人员
                                    for (int i = 0; i < condition.length; i++) {
                                        SMSreminder(jingbanStr[i], runId, runName, json, smsContent);
                                    }
                                    break;
                                case 3://3 发起人提醒
                                    if (flowRun != null) {
                                        seeReminder(flowRun.getBeginUser(), runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 4://4 发起人短信提醒
                                    if (flowRun != null) {
                                        SMSreminder(flowRun.getBeginUser(), runId, runName, json, smsContent);
                                    }
                                    break;
                                case 5://5 全部经办人提醒
                                    //获取全部经办人（已去除重复数据和当前用户）
                                    if (!StringUtils.checkNull(allUserId)) {
                                        seeReminder(allUserId, runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 6://6 全部经办人短信提醒
                                    if (!StringUtils.checkNull(allUserId)) {
                                        SMSreminder(allUserId, runId, runName, json, smsContent);
                                    }
                                    break;
                                case 7://7 催办提醒
                                    for (int i = 0; i < condition.length; i++) {
                                        handleReminder(beginStr[i], jingbanStr[i], runId, flowId, prcsId, condition[i], runName, tableName, tabId, users.getUserId(), sqlType, 0, smsContent);
                                    }
                                    break;
                                case 8://8 传阅人事务提醒
                                    // 如果用户勾选，将数组遍历
                                    if (!StringUtils.checkNull(viewUser)) {
                                        seeReminder(viewUser, runId, flowId, prcsId, currentPrcsId, runName, tableName, tabId, users.getUserId(), sqlType, smsContent);
                                    }
                                    break;
                                case 9://8 传阅人短信提醒
                                    if (!StringUtils.checkNull(viewUser)) {
                                        SMSreminder(viewUser, runId, runName, json, smsContent);
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
        });
    }

}